简体   繁体   English

零初始化的结构不会出现在内存中

[英]Zero-initialized struct not appear in memory

I am learning assembly and it amazed me that, a zero-initialized struct does not occupy in the memory. 我正在学习汇编,令我惊讶的是,零初始化的结构没有占用内存。 My code is like that. 我的代码就是这样。

// 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
};

then I compile the codes 然后我编译代码

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

However, when I use dd to read the binary in a.bin, I see 但是,当我使用dd读取a.bin中的二进制文件时,我看到

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

bar2 does not appear in the memory. bar2没有出现在内存中。 the 32-bits zero comes from bar1.filesize . 32位零来自bar1.filesize And (END) follows. 然后是(END)

I am learning 16bits x86 assembly, so the compile options may be strange. 我正在学习16位x86汇编程序,因此编译选项可能很奇怪。 But I think they won't cause this problem. 但我认为它们不会导致此问题。

Can anyone help me and explain why bar2 is "ignored"? 谁能帮我解释为什么bar2被“忽略”?

The compiler that places zero-inited stuff in the BSS, which the default linker script doesn't allocate space for in a flat binary ; 将零初始化内容放入BSS的编译器, 默认链接程序脚本不会在BSS 中为其分配空间 it starts after the end of the other sections. 它在其他部分结束之后开始。

Zero it yourself on startup before your C code runs, or disable the compiler's use of the BSS (eg -fno-zero-initialized-in-bss . 在您的C代码运行之前,您可以在启动时-fno-zero-initialized-in-bss ,或者禁用编译器对BSS的使用(例如-fno-zero-initialized-in-bss

You can look at gcc -S output; 您可以看一下gcc -S输出; note the .lcomm or .comm directives which reserve BSS space for all zero-init static / global variables. 请注意.lcomm.comm指令为所有零初始化静态/全局变量保留BSS空间。 When compiling a normal Linux executable, you don't want huge arrays of zeros explicitly stored in the executable. 在编译普通的Linux可执行文件时,您不希望在可执行文件中显式存储大量的零。

See https://gcc.gnu.org/ml/gcc-help/2007-07/msg00097.html for some discussion, eg you could use an __attribute__ to put an array that actually needs to be zero-inited into a different section, if you don't want to write a zero-init loop that runs on startup. 参见https://gcc.gnu.org/ml/gcc-help/2007-07/msg00097.html进行一些讨论,例如,您可以使用__attribute__将实际上需要零初始化的数组放入不同的部分,如果您不想编写在启动时运行的零初始​​化循环。 Then you can have some arrays that don't need to be initialized at all still in the BSS, but spend space in your binary for explicit zeros on other things that need it. 然后,您可以在BSS中拥有一些根本不需要初始化的数组,但是可以在二进制文件中花费一些空间来在需要它的其他事物上使用显式零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM