2010-04-15 73 views
6

对于C中的全局变量,如全局变量如何被精灵加载器初始化

int aglobal = 5;

5是什么时候被加载程序转移到aglobal中的?它是如何知道把5放到aglobal中的。

与函数中的静态声明相同的情况。像

int afunc() { static int astatic = 8; 返回astatic; }

回答

6

在数据部分创建一个int大小的空间,并在其中编码值5,并将名为'aglobal'的全局非函数符号添加到指向它的符号表中。对于aglobal的引用会变成在链接时解析为指向该数据块的重定位,因此在完全链接的映像中,指令将直接从内存中保存该值的那个点加载。例如, (x86)的组装可能看起来像:

.data 
.globl aglobal 
aglobal: .long 5 

.text 
main: 
    mov eax, aglobal 

在目标文件,MOV指令将变成mov eax, 0与搬迁R_386_32 aglobal+0,因为对象文件不肯定知道其中数据部分将在记忆。

在一个完全链接的图像,它可能是这样的:

mov eax, 0x804a010 

现在在数据部分中的4个字节的实际地址是已知的,所以它直接指定

+0

感谢这有助于。 纠正我,如果我错了... 因此,如果在我的代码中读取或写入aglobal,它正在访问.data节。 .data部分由加载器将elf文件中的.data部分复制到内存来初始化。 – newguy 2010-04-15 22:32:42

+0

正确的是,数据部分与文本部分一样被加载到内存中(但通常它是不可执行的,并且文本是不可写的,以尝试和防止漏洞)。在链接时,数据部分中特定单词的位置将被确定,并且引用它的所有指令(它们将具有名称'aglobal'的重定位)都被固定为指向该偏移量。所有加载器需要做的就是将整个映像从其基地址转移到它在内存中实际加载的地址(很多映像的基址为0,因此它只是添加了启动内存地址) – 2010-04-15 22:42:35

+0

谢谢。我很感谢Mike的帮助。 – newguy 2010-04-15 22:44:18