BSS(Block started By Symbol)部分中没有内容,因为它会浪费存储空间。BSS的内容全为零,在调用main之前,启动代码会将其清除。可以将BSS看作是一个游程长度压缩的字节块。要解压缩该块,您只需要知道值(0)和长度,它们存储在BSS的ELF条目中。 你的“数据已经初始化但还没有使用”的概念有点不对。考虑到ELF文件中的 * 所有 * 部分都是“尚未使用”的。文本段可能会被使用,也可能不会被使用(它可能包含死的/无法访问的代码)。数据段可能会被使用,也可能不会被使用(你可以定义代码从不使用的对象)。
2条答案
按热度按时间zaqlnxep1#
快速React是:嗯,没有内容填充
.bss
,所以在可执行文件中放置与该部分相关的任何数据没有意义。只有变量的位置被存储,但它属于另一个ELF部分。.bss
部分是程序中所有未初始化变量的地方(默认情况下所有变量都初始化为零)链接器只需要知道这个区域的实际大小和实际变量位置,而不是值,因为它的内容是显而易见的,与放置在那里的变量的性质或分布无关。当你的程序被加载时,内核通常会为程序的不可修改的文本分配一个只读段(
.text
部分),并在该段中放入初始化的const
变量的内容(.rodata
部分),所以如果你试图修改那里的内容,你会得到一个异常。然后是初始化数据部分,其中包含程序中所有初始化变量的初始值(.data
部分)和未初始化变量的初始值(.bss
部分)数据段(看看我如何调用不同的部分和加载段)被赋予更多的空间,
.data
和.bss
部分的总和,以容纳所有变量(两者都包括在内,所以这就是它使用其长度的原因)但是,虽然.data
部分的内容必须从文件中填充,但.bss
部分的内容不需要,因为在允许用户进程访问所分配的段之前,所有这些都被操作系统置零。对于小型系统来说,情况并非如此,在小型系统中,操作系统不会将数据填充为零。但是在那里,编译器添加了一些代码,将所有的.bss
段置零,所以再次说明,不需要从可执行文件中复制任何数据。这种行为的历史(和主要)原因是内核分配的页面必须与您的程序一起加载,出于安全原因被清除为零(因此您无法幸运地获得充满其他用户密码或其他敏感信息的页面),因此没有理由再次将其填充为零,并且没有任何东西必须复制到那里,没有理由将任何东西放在可执行文件上。内核通常维护的页面只有在它们要提供给用户时才归零,但会维护(因为它们是为此目的而设计的)信息,直到它们被覆盖。
o3imoua42#
BSS(Block started By Symbol)部分中没有内容,因为它会浪费存储空间。BSS的内容全为零,在调用
main
之前,启动代码会将其清除。可以将BSS看作是一个游程长度压缩的字节块。要解压缩该块,您只需要知道值(0)和长度,它们存储在BSS的ELF条目中。你的“数据已经初始化但还没有使用”的概念有点不对。考虑到ELF文件中的 * 所有 * 部分都是“尚未使用”的。文本段可能会被使用,也可能不会被使用(它可能包含死的/无法访问的代码)。数据段可能会被使用,也可能不会被使用(你可以定义代码从不使用的对象)。