您的位置:首页 > 产品设计 > UI/UE

[LinkerScript.12] 符号赋值: 源代码引用- Assigning Values to Symbols: SourceCodeReferenceq边接

2015-09-07 00:06 615 查看
Source Code Reference

Accessing a linker script defined 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.
在源代码中访问一个由链接器脚本定义的变量并不直观. 特别是链接器脚本符号并不能等同于声明在高级语言中的变量, 它是一个符号,而不是一个值.

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 defined in a linker script.
For example in C a linker script variable might be referred to as:


在进一步探究之前, 要特别注意当符号名称被存放符号表中时, 编译器经常转换源码中的名称为不同的名称.比如, Fortran编译器通常会加前导或后加一个下划线, 而C++会实现扩展"name mangling". 因此在用在源码中的变量名称和定义在链接器脚本中的相同变量名称可能存在差异.比如在C中可能象这样引用链接器脚本变量:

       extern int foo;


But in the linker script it might be defined as:
但是在链接器脚本中它是这样定义的:

       _foo = 1000;

In the remaining examples however it is assumed that no name transformation has taken place.
在下面的例子中, 假设不会发生名称转换.

When a symbol is declared in a high level language such as C, two things happen. The first 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 file scope:

当一个符号被声明在高级语言中,比如C, 有两件事会发生.  第一件事是编译器在程序的内存中预留足够的空间,用于存储符号的值. 第二件事是编译器创建程序的符号表,用来保存符号的地址. 比如 符号表包括着存储符号值的内存块的地址. 比如在文件中, 象C的声明:

       int foo = 1000;



creates an 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.
在符号表中创建一个叫做'foo'的符号.这个符号存储了一个'int'大小的内存块地址,这块地址上存储着初始化为1000的数据值.

When a program references a symbol the compiler generates code that first accesses the symbol table to find the address of the symbol's memory block and then code to read the value from that memory block.
So:

当一个程序引用一个符号时,编译器会生成访问符号表的代码,用于查找符号的内存块地址,然后代码从那个内存块上读取内容值.

       foo = 1;



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. Whereas:

查找符号表中的符号'foo',获得与这个符号相关联的地址,然后把1写入到这个地址上.然而

       int * a = & foo;



looks up the symbol ‘foo’ in the symbol table, gets its address and then copies this address into the block of memory associated with the variable ‘a’.

在符号表中查找符号'foo',获得它的地址,然后拷贝这个地址到与变量'a'相关的内存块上.

Linker scripts symbol declarations, by contrast, create an entry in the symbol table but do not assign any memory to them. Thus they are an address without a value. So for example the linker script definition:
链接器脚本符号声明,通过对比, 在符号表中创建一个符号,但不分配任何空间给它们.因此它们是一个无值的地址.例如链接器脚本是这样定义的:

       foo = 1000;



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 defined symbol - it has no value - all you can do
is access the address of a linker script defined symbol.

在符号表中创建一个称作'foo'的符号,存储着内存位置地址1000,但是没有在地址1000上存储任何内容.这表示你不能访问一个链接器脚本所定义的符号的值 - 它没有值 - 你可以做的是访问一个链接器脚本所定义的符号的地址.

Hence when you are using a linker script defined 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:

因此当你在源码中使用链接器脚本定义的符号时,你应该使用符号的地址,而且决不尝试使用它的值.比如假设你想要拷贝ROM存储器的一个section内容到FLASH的一个section中,链接器脚本包含这些声明:

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



Then the C source code to perform the copy would be:
C源码实现拷贝如下:

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




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


注意 '&'操作符的使用.这些都是正确的.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: