C 程序中 .bss 段的不明确行为

Ambiguous behaviour of .bss segment in C program

我写了下面这个简单的C程序(test.c):-

#include<stdio.h>
int main()
{
   return 0;
}

并执行以下命令以了解 .bss 段中的大小变化。

gcc test.c -o test
size test

输出结果为:-

   text    data     bss     dec     hex filename
   1115     552       8    1675     68b test

我没有声明任何全局或静态范围的内容。所以请解释为什么bss段大小是8字节。

我做了以下更改:-

#include<stdio.h>
int x;    //declared global variable
int main()
{
   return 0;
}

但令我惊讶的是,输出与之前相同:-

   text    data     bss     dec     hex filename
   1115     552       8    1675     68b test

请解释。 然后我初始化了全局:-

#include<stdio.h>
int x=67;    //initialized global variable
int main()
{
   return 0;
}

data segment size如期增加,没想到bss segment size减少到4(相反什么都没声明的时候是8)。请解释。

text       data     bss     dec     hex filename
1115        556       4    1675     68b test

我也尝试了命令 objdump 和 nm,但它们也显示变量 x 占用 .bss(在第二种情况下)。但是,在 size 命令上没有显示 bss 大小的变化。

我按照以下步骤操作: http://codingfox.com/10-7-memory-segments-code-data-bss/ 输出如预期的那样完美。

当您编译一个简单的 main 程序时,您也在链接启动代码。 此代码负责初始化 bss。

该代码是“使用”您在 .bss 部分中看到的 8 个字节的代码。

您可以使用 -nostartfiles gcc 选项删除该代码:

-nostartfiles

Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used

使用以下代码进行测试

#include<stdio.h>

int _start()
{
   return 0;
}

并用

编译
gcc -nostartfiles test.c

您会看到 .bss 设置为 0

   text    data     bss     dec     hex filename
    206     224       0     430     1ae test

你的前两个片段是相同的,因为你没有使用变量 x

试试这个

#include<stdio.h>
volatile int x;
int main()
{
   x = 1;
   return 0;
}

您应该会看到 .bss 尺寸发生了变化。

请注意,这 4/8 个字节是启动代码中的内容。如果不深入研究上述启动代码的所有细节,就不可能知道它是什么以及为什么大小不同。