理解C中数据bss段的大小命令
我从size命令得到意外的输出.
Afaik初始化存储在数据段中的全局和静态变量,未初始化并初始化为存储在bss段中的0个全局/静态变量. 的printf( “%d”,的sizeof(INT));给int大小4.但是,bss和数据段不会相应增加到4. #include <stdio.h> int main() { return 0; } C:Program Files (x86)Dev-CppMinGW64bin>size memory-layout.exe text data bss dec hex filename 10044 2292 2512 14848 3a00 memory-layout.exe #include <stdio.h> int g; //uninitialised global variable so,stored in bss segment int main() { return 0; } C:Program Files (x86)Dev-CppMinGW64bin>size memory-layout.exe text data bss dec hex filename 10044 2292 2528 14864 3a10 memory-layout.exe 为什么bss增加了16(2528 – 2512)而不是4? (在上面的代码中) #include <stdio.h> int g=0; //initialised to 0 so,stored in bss segment int main() { return 0; } C:Program Files (x86)Dev-CppMinGW64bin>size memory-layout.exe text data bss dec hex filename 10044 2292 2512 14848 3a00 memory-layout.exe 尽管使用全局变量,但bss没有增量.为什么? #include <stdio.h> int main() { static int g; //should be on bss segment return 0; } C:Program Files (x86)Dev-CppMinGW64bin>size memory-layout.ex text data bss dec hex filename 10044 2292 2512 14848 3a00 memory-layout.exe 尽管使用静态变量,bss段没有增量,为什么? 我还有一个问题,这里代表什么? 解决方法
首先要考虑的是内存对齐.可以填充变量和部分以使它们位于地址边界上.在第二个示例中,您看到第一个示例增加了16,这表示填充16字节边界(2512/16 = 157,2528 / 16 = 158).这完全取决于实现.
就C而言,第二个示例与第三个示例不同,因为编译器无法知道int g是定义还是仅仅是在另一个文件中定义的整数的声明(其中它可以是任何值).它为链接器留下了一个引用来代替,这可能会导致填充的差异. 在第三个示例中,g被明确定义并设置为0,因此编译器知道将其放在BSS部分中. 可以使用我系统生成的程序集来演示这一点: with int g(在这种情况下没有定义BSS部分) .comm g,4,4 这是链接器处理符号的指令,因为编译器无法完全确定如何处理它. int g = 0 .bss .align 4 .type g,@object .size g,4 g: .zero 4 这里编译器确切地知道要做什么,因此为符号定义了BSS部分. 在我的例子中,链接器以相同的方式解析它们.两者都放在同一地址的BSS部分,因此BSS大小没有差异.您可以使用nm等实用程序检查布局. nm -n file2 file3 | grep g$ 000000000060103c B g 000000000060103c B g 即在该系统上,g位于同一地址.或者,使用调试器: (gdb) info symbol 0x60103c g in section .bss of /tmp/file2 另请注意,在最后的示例中,变量可以优化,因为它具有内部链接. 至于十进制,它只是十进制各部分的总和. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |