4

我们知道 .bss 包含未初始化的变量。如果在 c 代码中,程序员在使用它们之前初始化变量。那么 .bss 在执行 C 代码之前不必为零。

我对吗?

谢谢

4

4 回答 4

17

在 C 代码中,任何具有静态存储持续时间的变量都被规范定义为初始化为 0(第 6.7.8 节初始化,第 10 段):

如果具有静态存储持续时间的对象未显式初始化,则:

  • 如果是指针类型,则初始化为空指针;
  • 如果它具有算术类型,则将其初始化为(正或无符号)零;
  • 如果是聚合,则每个成员都根据这些规则(递归地)初始化;
  • 如果是联合,则根据这些规则(递归地)初始化第一个命名成员。

一些程序加载器会在开始时用零填充整个部分,而其他程序加载器将“按需”填充它作为性能改进。因此,虽然您在技术上是正确的,当 C 代码开始执行时,该.bss部分可能并不真正包含全零,但它在逻辑上确实如此。无论如何,假设您有一个符合标准的工具链,您可以将其视为全零。

任何初始化为非零值的变量都不会出现在该.bss部分中;根据它们的特定特性,它们在.data或部分中处理。.rodata

于 2010-08-20T15:28:36.093 回答
6

ELF 规范说:

.bss 此部分保存有助于程序内存映像的未初始化数据。根据定义,系统在程序开始运行时用零初始化数据。该节不占用文件空间,如节类型 SHT_NOBITS 所示。

因此,一个有赋值的 C 全局变量不能放入 .bss 部分,而必须放入 .data 部分。.data 部分包含分配给它的所有变量的初始值。

于 2010-08-20T15:57:10.773 回答
1

这取决于变量在代码中的位置。例如,如果您正在谈论 main() 或任何其他函数中的局部变量,那么变量将被推入堆栈(除非您使用其他修改关键字)。如果您的变量是全局变量并且未初始化,那么它应该保存在 .bss 中。请注意,编译器优化等可能会改变一些事情。如果您想确定使用 readelf 来研究 linux 上的 ELF 二进制文件。

于 2010-08-20T15:29:09.540 回答
-1

您似乎对 .bss 部分最终初始化为零的机制感到困惑。您编译的代码不必显式将该区域初始化为零,因为当操作系统首次为进程分配新的内存页面时,操作系统会确保该页面被初始化为零。这样做是出于安全原因,这样一个进程就无法在其他进程退出时寻找留在内存中的秘密。

于 2010-08-20T15:57:54.977 回答