如果这个问题太琐碎,请原谅我!众所周知,最终的可执行文件不会为映像中的未初始化数据分配空间。但我想知道,如何解决对 .bss 中符号的引用?
目标文件是否仅包含 .bss 的这些变量的地址,而不是为它们分配空间?如果是这样,这些解析的地址存储在哪里?
例如。如果在 C 模块中我有类似以下全局变量的东西 -
诠释 x[10];字符 chArray[100];
上述变量的空间可能不存在于图像中,但如何引用它们?他们的地址在哪里解决?
提前致谢!/多发性硬化症
.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 部分中。正是在这一点上,他们得到了他们的地址。