为什么我不在BSS中获得静态变量?

时间:2015-10-16 10:16:19

标签: c gcc memory

根据我的理解,未明确初始化的静态变量(以及GCC,即使设置了-fzero-initialized-in-bss时明确初始化为零的静态变量,通常也会存储)在BSS部分。然而,当我尝试检查该行为时,这些变量似乎存储在通用数据部分中(使用初始化的全局变量)。如果我编译(使用-O0进行测量)并运行:

#include <stdio.h>
#include <stdlib.h>

extern char etext, edata, end;

int i = 42;

int main(int argc, char* argv[])
{
        static int j;
        printf ("end of program (etext) = %10p\n",&etext);
        printf ("end of initialized data (edata) = %10p\n",&end);
        printf ("end of uninitialized data (end) = %10p\n",&end);
        printf ("=====\n");
        printf ("Value of i (initialized global) : %d\n",i);
        printf ("Address of i : %10p\n",&i);
        printf ("Value of j (static with no explicit initialization) : %d\n",j);
        printf ("Address of i : %10p\n",&j);
        return 0;
}

我得到了输出:

end of program (etext) =   0x40067d
end of initialized data (edata) =   0x600af0
end of uninitialized data (end) =   0x600af0
=====
Value of i (initialized global) : 42
Address of i :   0x600ae0
Value of j (static with no explicit initialization) : 0
Address of i :   0x600ae8

因此ij存储在&etext&edata之间的连续内存地址,这是常规数据部分。此外,似乎&edata == &end如果我理解正确,则意味着BSS是空的。

现在我意识到编译器放置哪个变量是一个实现选择,它产生的结果是正确的。但我只是想知道为什么我会得到这种行为,如果有办法告诉gcc明确地将这些变量放在BSS中(我在手册中没有看到任何明显的解决方案)。

2 个答案:

答案 0 :(得分:3)

您的代码中有错误。你为edata和end打印end的地址,所以当然你假设edata == end,它们不是。

当我修复代码并运行它时,我得到:

  

程序结束(etext)= 0x8048578
  初始化数据结束(edata)= 0x804988c
  未初始化数据的结尾(结束)= 0x8049894

     

i的值(初始化全局):42
  地址:i:0x8049888
  j的值(没有显式初始化的静态):0
  地址j:0x8049890

很清楚j位于edata和end之间的区域,与i不在同一个地方。

(gcc 5.2.1 20150911(Debian 5.2.1-17),32bit)

答案 1 :(得分:1)

可执行映像中的BSS只是一个数字,表示在未初始化变量加载时要保留多少字节。通过这种方式,对于许多未初始化的变量,图像不会变得非常大。当数字很小时,例如在你的例子中,几乎没有任何保存和开销,编译器可能已经决定将它们全部放在DATA段中。

相关问题