如何在最终图像中解析.bss的变量?

时间:2009-12-27 15:19:12

标签: linker loader

请原谅我,如果这个问题太琐碎了!众所周知,最终的可执行文件不为图像内的未初始化数据分配空间。但我想知道,.bss中符号的引用是如何解决的?

对象文件是否只包含.bss的这些变量的地址,其他地方是什么,而不是为它们分配空间?如果是,那么存储这些已解析的地址在哪里?

例如。如果在C模块中我有类似跟随全局变量的东西 -

int x [10]; char chArray [100];

上述变量的空间可能不会出现在图像中,但是如何引用它们?他们的地址在哪里解决了?

提前致谢! / MS

1 个答案:

答案 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部分中。正是在这一点上,他们得到了他们的地址。