请原谅我,如果这个问题太琐碎了!众所周知,最终的可执行文件不为图像内的未初始化数据分配空间。但我想知道,.bss中符号的引用是如何解决的?
对象文件是否只包含.bss的这些变量的地址,其他地方是什么,而不是为它们分配空间?如果是,那么存储这些已解析的地址在哪里?
例如。如果在C模块中我有类似跟随全局变量的东西 -
int x [10]; char chArray [100];
上述变量的空间可能不会出现在图像中,但是如何引用它们?他们的地址在哪里解决了?
提前致谢! / MS
答案 0 :(得分:2)
.bss符号就像编译器(或汇编程序)生成的任何其他符号一样得到解析。通常这通过在“部分”中放置相关符号来起作用。例如,编译器可能将程序代码放在名为“。text”的部分中(出于历史原因;-),在名为“.data”的部分中初始化数据,并在名为“.bss”的部分中放置单元化数据。
例如:
int i = 4;
int x[10];
char chArray[100];
int main(int argc, char**argv)
{
}
生成(使用gcc -S):
.file "test.c"
.globl i
.data
.align 4
.type i, @object
.size i, 4
i:
.long 4
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.comm x,40,32
.comm chArray,100,32
.ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
.section .note.GNU-stack,"",@progbits
.data指令告诉汇编器将i放在数据部分,“。long 4”给它初始值。组装文件时,i将在数据部分的偏移0处定义。
.text指令将main放在.text部分中,同样偏移量为零。
这个例子的有趣之处在于x和chArray是使用.comm指令定义的,而不是直接放在.bss中。两者都只给出了一个尺寸,而不是一个偏移量。(
)当链接器获取目标文件时,它通过组合具有相同名称的所有部分并相应地调整符号偏移量将它们链接在一起。它还为每个部分提供了一个应该加载它的绝对地址。
组合.comm指令定义的符号(如果存在多个具有相同名称的定义)并放在.bss部分中。正是在这一点上,他们得到了他们的地址。