您的位置:时时app平台注册网站 > 编程知识 > 链接脚本文件中定义的标识怎么在c源文件,汇编

链接脚本文件中定义的标识怎么在c源文件,汇编

2019-11-28 03:22

代码来自(Kithgard地牢45关Mightier Than the Sword)

extern int foo;

password = 'Secret Message'

book@book-desktop:~/exam/inline_asm$ objdump -h exam1_elf 

exam1_elf:     file format elf32-little

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000002c  00000000  00000000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .glue_7       00000000  0000002c  0000002c  0000802c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .glue_7t      00000000  0000002c  0000002c  0000802c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .data         00000000  0000002c  0000002c  0000802c  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  4 .bss          00000000  0000002c  0000002c  0000802c  2**0
                  ALLOC

# A variable is a way of holding on to a value.

除此以外二个友好做试验的事例
Makefile

#概念密码为'Secret Message'

时时app平台注册网站 1

#变量是少年老成种保存值的法子。

foo = 1000;

#移动到最终生机勃勃扇门并讲出新密码变量'Let Me Out Of Here'以打开它。
hero.say(password)

在c语言里面声美赞臣个symbol,首先编写翻译器会保留丰富的空中去存款和储蓄那份symbol的值,然后会在符号表中增添三个规行矩步来保存symbol的值,例子说的很显然,首先symbol table中会增多二个entry,名字称为foo,这一个entry保存着foo变量的地址,地址里面存的剧情是1000

#每当你给变量授予新的值时,变量都会换为新的值。

.global _start
.global _bss_start
_bss_start:

    .word __bss_start
.global abcd

abcd:
    .word 0x1234
.global _dd
_dd:
    .word __dd
_start:
    mov r0, #1
    nop
    nop
    adr r1, _bss_start
    adr r2, _dd
    nop
    ldr r3, =__dd

#给变量”password“付与新的值“'So Many Doors'
password = 'So Many Doors'
hero.moveRight()
# Change the string in this line to the password variable.

c代码中应用变量见上方,须要用extern注解.然后在取地址.

 

Accessing a linker script defned variable from source code is not intuitive. In particular a
linker script symbol is not equivalent to a variable declaration in a high level language, it
is instead a symbol that does not have a value.

# 在“说“变量时候不要加引号,直接输入变量名称。此处说的密码正是新的值”So Many Doors”
hero.say(password)
hero.moveRight()

把反汇编的代码得到keil里去仿真,结果与地点分析的同等

# A variable changes its value whenever you assign it.

looks up the symbol ‘foo’ in the symbol table, gets it address and then copies this address
into the block of memory associated with the variable ‘a’
//foo的地址 --->a变量

password = 'Let Me Out Of Here'
# Move to the last door and say the password variable to open it.

参考文书档案:
the Gnu Linker ld
 3.5.4 Source Code Reference

# Here the "password" variable holds the secret phrase we need.#这里“password”变量保存大家必要的密码。

Linker scripts symbol declarations, by contrast, create an entry in the symbol table but donot assign any memory to them. Thus they are an address without a value. So for example the linker script defnition:
//链接脚本里声称变量的话只会在symbol table里面增添entry,不会为其分配内部存款和储蓄器.

 

_foo = 1000;

hero.moveUp()
hero.moveRight()
hero.say(password) #透露变量“password”中满含的值'Secret Message'

looks up the symbol ‘foo’ in the symbol table, gets the address associated with this symbol
and then writes the value 1 into that address.
//那几个事例表明对变量foo的探问首先去 symbol table获取foo地址,然后往改地址写入1
Whereas:

Hence when you are using a linker script defned symbol in source code you should always
take the address of the symbol, and never attempt to use its value. For example suppose
you want to copy the contents of a section of memory called .ROM into a section called
.FLASH and the linker script contains these declarations:

start_of_ROM = .ROM;
end_of_ROM = .ROM   sizeof (.ROM) - 1;
start_of_FLASH = .FLASH;

编写翻译器平日会把源代码中的name(变量名也许函数名)实行调换然后在寄放在symbol table,举个例子fortran通常会在name的前或后加下划线,由此等同的变量在源代码四之日链接脚本中名字或许不平等

exam1_elf:     file format elf32-littlearm

Disassembly of section .text:

00000000 <_bss_start>:
   0:   0000002c    andeq   r0, r0, ip, lsr #32

00000004 <abcd>:
   4:   00001234    andeq   r1, r0, r4, lsr r2

00000008 <_dd>:
   8:   0000002c    andeq   r0, r0, ip, lsr #32

0000000c <_start>:
   c:   e3a00001    mov r0, #1  ; 0x1
  10:   e1a00000    nop         (mov r0,r0)
  14:   e1a00000    nop         (mov r0,r0)
  18:   e24f1020    sub r1, pc, #32 ; 0x20
  1c:   e24f201c    sub r2, pc, #28 ; 0x1c
  20:   e1a00000    nop         (mov r0,r0)
  24:   e51f3004    ldr r3, [pc, #-4]   ; 28 <.text 0x28>
  28:   0000002c    andeq   r0, r0, ip, lsr #32
foo = 1;

exam.lds链接脚本

.globl _bss_start
_bss_start:
    .word __bss_start

creates a entry called ‘foo’ in the symbol table. This entry holds the address of an ‘int’
sized block of memory where the number 1000 is initially stored.

keil仿真结果

When a symbol is declared in a high level language such as C, two things happen. The frst is that the compiler reserves enough space in the program’s memory to hold the value of
the symbol. The second is that the compiler creates an entry in the program’s symbol table
which holds the symbol’s address. ie the symbol table contains the address of the block of memory holding the symbol’s value. So for example the following C declaration, at fle scope

exam1.S文本,小编一直动用lds脚本里的__dd,取其值存入r3,编写翻译竟然能通过.也绝非报错说并未有找到__dd.

查看.text段有多大,大小是0x2c,反汇编看一下终极r3存放器是还是不是0x2c

But in the linker script it might be defned as:

creates an entry in the symbol table called ‘foo’ which holds the address of memory location
1000, but nothing special is stored at address 1000. This means that you cannot access the
value of a linker script defned symbol - it has no value - all you can do is access the address
of a linker script defned symbol.

Then the C source code to perform the copy would be:

SECTIONS {
    .text : {*.text}
    __bss_start = .;
    __bss_end   = .;
    __dd        = .;
}

exam1_dis反汇编文件
24: e51f3004 ldr r3, [pc, #-4] ; 28
r3确实是0x2c

exam.bin:exam1.o
    arm-linux-ld -Texam.lds -o exam1_elf $<
    arm-linux-objdump -D -m arm exam1_elf > exam1_dis


%.o:%.c
    arm-linux-gcc -c $< 

%.o:%.S
    arm-linux-gcc -c $< 


clean:  
    rm *.o *.bin *_dis *_elf

Before going further, it is important to note that compilers often transform names in the
source code into different names when they are stored in the symbol table. For example,
Fortran compilers commonly prepend or append an underscore, and C performs extensive
‘name mangling’. Therefore there might be a discrepancy between the name of a variable
as it is used in source code and the name of the same variable as it is defned in a linker
script

For example in C a linker script variable might be referred to as:

Note the use of the ‘&’ operators. These are correct.

int foo = 1000;

从源文件中拜谒链接脚本中定义的变量不可能直接待上访谈,链接脚本中的变量是贰个符号实际不是叁个宛在前段时间的值

extern char start_of_ROM, end_of_ROM, start_of_FLASH;
memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM);

however it is assumed that no name transformation has taken place.

When a program references a symbol the compiler generates code that frst accesses the
symbol table to fnd the address of the symbol’s memory block and then code to read the
value from that memory block. So:
//程序援引贰个symbol时首先在symbol table里面查找symbol之处,然后在把那一个地方里面包车型客车数据读抽出来

asm文件之中怎么利用啊?好疑似足以直接就利用.word把__bss_start的值存在标号_bss_start处也便是*_bss_start = __bss_start的值

地点的例子只是在symbol table成立了三个foo,地址是1000,1000为地方的内部存款和储蓄器里面什么内容都不曾,所以你不可能访问foo(1000里头的剧情),你只好获得foo之处(1000)

int * a = & foo;

本文由时时app平台注册网站发布于编程知识,转载请注明出处:链接脚本文件中定义的标识怎么在c源文件,汇编

关键词: