所有全局初始化值都存储在.data段中.i.e。初始化的数据段和未初始化的值存储在bss中,编译器在bss中自动将那些未启动的值初始化为零。然后为什么数据段被分隔为.data和bss。
是否有优势?或任何好处
答案 0 :(得分:5)
C编程语言(这是一个用英语编写的规范)不了解 #video-background {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 75%;
width: auto;
height: auto;
z-index: -100;
}
或.bss
或data segment。请阅读n1570(C11的最新草稿)。
在某些情况下(例如嵌入式计算),您没有任何数据段。例如,当cross-compile为Arduino时,生成的代码会上传到该微控制器的闪存中(并且数据位于RAM中,您的程序可能明确地清除)。
(我下面的大部分答案都集中在Linux上,但您可以将其改编为其他操作系统)
关于像Linux这样的类Unix系统上的data segment,请阅读更多ELF的规范。 方便是为了避免在executable文件中花费文件空间来存放全部为零的内容(.bss
)。 kernel的execve(2)代码可以设置初始virtual address space,其中包含一些已清除的数据(不 mapped to some file段)。另见mmap(2)& elf(5)& ld-linux(8)。尝试使用.data
命令来了解shell的虚拟地址空间。请参阅proc(5)。
因此,可执行文件包含segments(其中一些全部为零且不占用任何磁盘空间),并由linker构建,它也处理relocations - 来自来自object files文件的compiler提供了多个source code。在Linux上,使用objdump(1)和readelf(1)(和nm(1) ...)来探索和检查ELF可执行文件和ELF目标文件。
顺便说一句,virtual memory子系统不需要从磁盘中提取已清除的数据段,这可能会使稍微更快。当内核为page时,内核只会在RAM中清除paged。
因此存在cat /proc/$$/maps
以避免浪费可执行文件中的磁盘空间(以及加速初始化归零数据)。显然,一些可变数据被显式初始化为非零内容(并且需要位于.bss
并占用可执行文件中的一些磁盘空间)。常量不可变只读数据进入.data
(进入text segment,通常由运行相同程序的多个processes共享)
您可以配置链接器(例如,使用某个链接器script)将所有数据(甚至是已清除的数据)放入某些显式data segment中(但这样做只是浪费磁盘空间)。 ....历史上,Unix have been developed machines只有很少但成本高昂的磁盘空间(因此浪费它在当时是不可想象的,因此需要.rodata
;今天你不在乎!)< / p>
阅读Levine的书Linkers and Loaders了解更多信息,Advanced Linux Programming和Operating Systems : Three Easy Pieces。