【问题标题】:What data do BSS and data segment have by default?BSS和数据段默认有哪些数据?
【发布时间】:2025-11-28 04:20:06
【问题描述】:

我开发了一个简单的C程序如下图..

int main()
{
    return 0;
}

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

文本 = 1131,数据 = 552,bss = 8

据我了解,数据部分保存已初始化的全局数据,而 BSS 保存未初始化的全局数据。虽然没有全局变量,为什么“数据”和“BSS”部分显示非零值?

【问题讨论】:

  • 有很多运行时代码链接到您的程序,例如启动代码.
  • @FelixPalmen 对。知道这两个段中的数据到底是什么吗?
  • 这在很大程度上取决于您的目标平台以及您的运行时在调用main() 之前必须执行的任务。例如,它必须设置agrv[]。大多数情况下,会涉及初始化循环,因为您未显式初始化的数据放在.bss 中,因此必须设置为0,然后您的程序才能启动......等等。 pp.

标签: c linux unix


【解决方案1】:

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

【讨论】:

  • 有道理。通过实现,您的意思是我的编译器,即它添加额外代码的方式?有什么办法可以检查吗?我使用 gcc v5.2.1。你能提供一些提示吗?
  • gcc 使用目标文件crt*.o 直接链接到您的可执行文件(crt 表示“C 运行时”)。在我的 Linux 系统上,我在 /usr/lib/gcc/x86_64-linux-gnu 中找到它们,您系统上的路径可能会有所不同。根据您的编译方式,它还可能链接libgcc.a
【解决方案2】:

回答您的问题:启动代码有自己的数据。该数据显示在此示例中。

如何调用段由实现定义,但大多数启动代码和链接器脚本都使用这个最流行的。

.text - 你的程序代码

.rodata - 仅限 RO 的数据 - 例如字符串文字。许多实现将带有const (const int x[2] = {1,2};) 的对象放在那里

.bss - 带有静态存储(即全局)的未初始化数据

在 C 中,没有显式初始化程序的静态分配对象是 初始化为零(对于算术类型)或空指针(对于 指针类型)。 C 的实现通常表示零值 和空指针值使用仅由以下组成的位模式 零值位(尽管这不是 C 标准所要求的)。 因此,BSS 段通常包括所有未初始化的对象 (变量和常量)在文件范围(即外部 任何函数)以及未初始化的静态局部变量(local 用 static 关键字声明的变量);静态局部常量 但是,必须在声明时初始化,因为它们没有 单独的声明,因此通常不在 BSS 部分中, 尽管它们可能被隐式或显式初始化为零。一个 实现也可以分配静态分配的变量和 用仅由零值组成的值初始化的常量 位到 BSS 部分。

.data -

.data 段包含任何具有 预定义的值,可以修改。那是任何变量 未在函数中定义(因此可以从任何地方访问) 或在函数中定义,但被定义为静态,因此它们保留 他们在后续调用中的地址。

示例:

 static char x[] = "Hello world";

字符串文字“Hello world”存储在 .rodata 段中,并在启动期间复制到位于 .data 段中的 char 表 x。

【讨论】:

    最近更新 更多