请完成以下程序 -
#include <stdio.h>
void main()
{
}
为每个段分配的内存如下(通过在Unix上使用size命令) -
text data bss dec hex filename
1040 484 16 1540 604 try
声明全局变量后 -
#include <stdio.h>
int i;
void main()
{
}
为每个段分配的内存如下(在Unix上使用size命令) 这里变量'i'已经在BSS中接收到了内存(以前是16,现在是24) -
text data bss dec hex filename
1040 484 24 1548 60c try
声明全局变量并用10 -
初始化它#include <stdio.h>
int i=10;
void main()
{
}
为每个段分配的内存如下(在Unix上使用size命令) 变量'i'在数据段中收到了内存(以前是484,现在是488) -
text data bss dec hex filename
1040 488 16 1544 608 try
我的问题是为什么全局变量'i'在存储在BSS中时得到大小为8字节的内存,但是当它存储在数据段中时得到4字节? 为什么在BSS和数据段中为内存分配内存存在差异?
答案 0 :(得分:1)
为什么全局变量&#39; i&#39;当它存储在BSS中时获得了大小为8字节的内存,但当它存储在数据段中时却得到了4个字节?
First, why 4 bytes in data segment?
许多人已经回答过这个问题 - .data段包含任何事先初始化的全局变量或静态变量。整数的大小为4个字节,当您的程序中包含全局int i=10;
时,它将反映在数据段大小中。
Now, why 8 bytes in .bss segment?
由于GNU链接器 GNU ld 的默认链接描述文件,您正在观察此行为。您可以获取有关链接描述文件here的信息。
链接时,GNU链接器(GNU ld)正在使用默认的链接描述文件。
默认链接描述文件指定.bss段的对齐方式。
如果要查看默认链接描述文件,可以使用命令 -
执行此操作gcc -Wl,-verbose main.c
此gcc
命令的输出将包含以下语句:
using internal linker script:
==================================================
// The content between these two lines is the default linker script
==================================================
在默认链接描述文件中,您可以找到.bss
部分:
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
在这里,您可以看到. = ALIGN(. != 0 ? 64 / 8 : 1);
表示默认对齐为8个字节。
该计划:
#include <stdio.h>
int i;
void main()
{
}
使用默认链接描述文件构建时,&#39; i&#39;由于8字节对齐,在BSS中获取大小为8字节的内存:
# size a.out
text data bss dec hex filename
1040 484 24 1548 60c a.out
[bss = 24字节(16 + 8)]
GNU链接器提供了一个将您自己的链接描述文件传递给它的规定,在这种情况下,它使用传递给它的脚本来构建目标而不是默认的链接描述文件。
只是为了尝试这个,您可以在文件中复制默认链接描述文件的内容,并使用此命令将链接描述文件传递给GNU ld
:
gcc -Xlinker -T my_linker_script main.c
由于您可以拥有自己的链接描述文件,因此您可以对其进行更改并查看行为的变化。
在.bss
部分中,将此. = ALIGN(. != 0 ? 64 / 8 : 1);
更改为. = ALIGN(. != 0 ? 32 / 8 : 1);
。这会将默认对齐方式从8个字节更改为4个字节。现在使用链接描述文件通过此更改构建目标。
输出结果为:
# size a.out
text data bss dec hex filename
1040 484 20 1544 608 a.out
由于4字节对齐,您可以看到bss
大小为20
字节(16 + 4)。
希望这能回答你的问题。