[英]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.