C程序中.bss段的歧义行为

8
我编写了下面这个简单的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;
}

数据段的大小按预期增加,但我没想到bss段的大小会减少到4(与未声明时的8相反)。请解释。
text       data     bss     dec     hex filename
1115        556       4    1675     68b test

我也尝试了objdump和nm命令,但它们也显示变量x占用.bss(在第2种情况下)。然而,size命令没有显示bss大小的变化。
我按照以下步骤进行操作: http://codingfox.com/10-7-memory-segments-code-data-bss/ 输出结果与预期完全相符。
2个回答

7
当您编译一个简单的main程序时,也会链接启动代码。该代码负责初始化bss等任务。那段代码就是您在.bss节中看到的使用了8个字节的代码。您可以使用-nostartfiles gcc选项去除该代码:

-nostartfiles

链接时不使用标准系统启动文件。标准系统库通常会被使用,除非使用了-nostdlib或-nodefaultlibs选项。

为了进行测试,请使用以下代码。
#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

你好,我尝试使用-nostartfiles标志进行相同的操作,但是当运行可执行文件时出现了“Hello world segmentation fault (code dumped)!”这是为什么?此外,当我使用“gcc-Wall-nostartfiles1test.c”编译时,它会给出:“/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008048230”。考虑到我的程序:#include<stdio.h> int main(){ printf("Hello world\n"); return 0; } - Dr. Essen
正如警告所说:如果您使用 -nostartfiles 删除了标准启动文件,则必须提供一个 _start 函数作为代码的入口点。 - LPs

2

由于您没有使用变量 x,因此您的前两个片段是相同的。

尝试这样做:

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

你应该看到.bss大小发生了变化。

请注意,这4/8个字节是在启动代码内部的某些内容。如果不深入挖掘所提及的启动代码的所有细节,就无法确定它是什么以及为什么大小会有所不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接