BSS和数据段默认包含哪些数据?

3
我开发了一个简单的 C 程序,如下所示:
int main()
{
    return 0;
}

我使用gcc v5.2.1编译了该程序。当我在可执行文件上运行Unix命令“size”时,它显示了以下大小...

text = 1131, data = 552, bss = 8

据我所知,数据段保存已初始化的全局数据,BSS保存未初始化的全局数据。尽管没有全局变量,为什么“data”和“BSS”部分显示非零值?

1
你的程序与许多运行时代码相关联,例如启动代码 - user2371524
@FelixPalmen 对的。有没有想法,这两个部分的数据具体是什么? - Parth Shah
3
这在很大程度上取决于你的目标平台以及运行时在调用main()之前必须执行的任务。例如,它必须设置argv[]。大多数情况下,都涉及到初始化循环,因为你没有明确初始化的数据会被放置在.bss中,因此在程序开始之前必须设置为0 ...等等。 - user2371524
2个回答

2
简而言之:因为你的最终程序包含的代码不仅仅是你编写的部分。它必须包含一些运行时,例如在调用main()之前需要执行所有设置(如填充argv,将.bss中的数据初始化为零等),以及退出后的清理工作。这段代码究竟做了什么完全取决于你的实现方式。

有道理。你的实现是指我的编译器,也就是它添加额外代码的方式?我该怎么检查呢?我使用gcc v5.2.1。你能提供一些提示吗? - Parth Shah
gcc使用对象文件crt*.o直接链接到您的可执行文件(其中crt表示“C运行时”)。在我的Linux系统上,我发现它们位于/usr/lib/gcc/x86_64-linux-gnu,在您的系统上路径可能会有所不同。根据您的编译方式,它还可能链接libgcc.a - user2371524

0
回答你的问题:启动代码有自己的数据。这个例子中展示了这些数据。
段的名称如何被称呼是由实现定义的,但大多数启动代码和链接脚本使用最流行的一个。
.text - 你的程序代码
.rodata - 只读数据 - 例如字符串字面量。许多实现将带有const(const int x [2] = {1,2};)的对象放在那里
.bss - 静态存储器中未初始化的数据(即全局变量)。
在C语言中,没有显式初始化的静态分配对象会被初始化为零(对于算术类型)或空指针(对于指针类型)。C的实现通常使用仅由零值位组成的位模式来表示零值和空指针值(尽管这不是C标准所要求的)。因此,BSS段通常包括在文件作用域(即任何函数之外)声明的所有未初始化对象(变量和常量),以及未初始化的静态局部变量(使用static关键字声明的局部变量);但静态局部常量必须在声明时进行初始化,因为它们没有单独的声明,因此通常不在BSS段中,尽管它们可以隐式或显式地初始化为零。实现还可以将静态分配的变量和常量赋值为仅由零值位组成的值,并将其分配到BSS段中。
.data -
.data段包含任何具有预定义值且可修改的全局或静态变量。也就是说,任何不在函数内定义(因此可以从任何地方访问)或在函数内定义但被定义为静态的变量,以便它们在后续调用中保留其地址。

例子:

 static char x[] = "Hello world";

字符串字面量""Hello world"存储在.rodata段中,并在启动期间复制到.char表x中,该表位于.data段中。


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