零初始化结构未出现在内存中

Zero-initialized struct not appear in memory

我正在学习汇编,令我惊讶的是,一个零初始化的结构体不占用内存。 我的代码就是这样。

// in file a.cpp
#include <stdint.h>
struct Bar {
    char filename[8];
    // ignore members here
    uint32_t filesize;
}__attribute__((packed));

typedef struct FAT_ITEM FAT_ITEM;

Bar bar1 = {
    "null",0
};
Bar bar2 = {
    "",0
};

然后我编译代码

gcc -march=i386 -m16 -mpreferred-stack-boundary=2 -ffreestanding -O0 a.cpp a.o
ld -melf_i386 -N --oformat binary -o a.bin a.o

但是,当我使用 dd 读取 a.bin 中的二进制文件时,我看到

00000000: 6e75 6c6c 0000 0000 0000 0000            null........
(END)

bar2没有出现在内存中。 32 位零来自 bar1.filesize(END) 紧随其后。

我正在学习 16 位 x86 汇编,所以编译选项可能很奇怪。但我认为他们不会造成这个问题。

谁能帮我解释一下为什么 bar2 是 "ignored"?

在 BSS 中放置 zero-inited 东西的编译器,;它在其他部分结束后开始。

在 C 代码运行之前在启动时自行将其清零,或禁用编译器对 BSS 的使用(例如 -fno-zero-initialized-in-bss

你可以看看gcc -S输出;注意 .lcomm or .comm directives 为所有 zero-init 静态/全局变量保留 BSS space。编译普通 Linux 可执行文件时,您不希望在可执行文件中显式存储大量零数组。

请参阅 https://gcc.gnu.org/ml/gcc-help/2007-07/msg00097.html 进行一些讨论,例如如果您不想编写在启动时运行的 zero-init 循环,则可以使用 __attribute__ 将实际需要 zero-inited 的数组放入不同的部分。然后你可以在 BSS 中有一些根本不需要初始化的数组,但是在你的二进制文件中花费 space 用于在其他需要它的东西上显式置零。