为什么.bss显式地将全局变量初始化为零?

时间:2012-07-11 03:08:58

标签: c gcc assembly mips

我正在生成mips反汇编以模拟它。我需要有大数据来处理它,但我不想拥有大的汇编文件,所以我想要处理一个大的未初始化的数组(然后可能在我的模拟器中初始化它...)。所以我需要这个数组是全局的。并且全局变量似乎放在.bss部分,以便在实际访问页面时进行初始化。 问题是在我的二进制文件中,数组在.bss部分,但显式填充为零...如果我正确理解我在互联网上找到的内容,这不是预期的行为......有没有办法说编译器(或链接器,或者加载器......我不太清楚哪个做了什么)在这个数组中没有真正归零? 或者,我们可以在编译时有一个选项,还是一个C指令,说我们不希望这个数组用0初始化? (我尝试使用属性更改数组部分,但仍然使用0进行初始化。)

顺便说一下,我用objdump生成我的反汇编文件,它通常跳过零块,但我真的需要反汇编其他的零块,所以我使用“-z”选项。

我真正不明白的是,无论我看到的是什么,都说.bss部分并没有真正在二进制文件中添加零...

2 个答案:

答案 0 :(得分:8)

.bss部分的数据没有存储在编译的目标文件中,因为没有数据 - 编译器将变量精确地放在中,因为它们应该是零初始化的

当操作系统加载可执行文件时,它只会查看.bss段的大小,分配那么多内存,并为您进行零初始化。通过不将该数据存储在可执行文件中,可以减少加载时间。

如果您希望使用某些数据初始化数据,请在代码中为其初始化。然后编译器将其放入.data段(初始化数据)而不是.bss(未初始化数据)。当操作系统加载可执行文件时,它将为数据分配内存,然后从可执行文件中复制它。这需要额外的I / O,但您的数据会以您希望的方式显式初始化。

或者,您可以将数据保留在.bss段中,然后在运行时自行初始化。如果数据在运行时快速且容易生成,则在启动时重新计算数据可能会更快,而不是从磁盘读取数据。但这些情况可能很少见。

答案 1 :(得分:0)

我怀疑使用-z选项会导致objdump显示.bss的零,即使零实际上不在您的二进制文件中。尝试使用od -t x4来获取二进制文件中真正的十六进制转储。如果od显示零块,则它们实际上是二进制文件。