我在学习的时候遇到了一个小问题。我知道 C 中未初始化的全局变量被分配给可执行 ELF 文件中的 .bss 部分。但是当我开始使用它们时它们会发生什么?即,他们是在堆上还是在其他地方占有一席之地?
我试图通过打印(仍未初始化的)全局变量的地址来找出答案
printf("%x",&glbl);
它总是返回相同的值 0x80495bc ...为什么?
当操作系统加载您的程序时,它会从您的程序地址空间分配足够的存储空间来存储 .bss 部分中的所有内容并将所有内存归零。当您分配或读取或获取变量的地址时,您正在操作分配的内存以提供 .bss 部分的存储空间。
全局变量总是获得静态内存,如果它们未初始化,它们在二进制文件中没有空间,但是当二进制文件加载到进程内存空间时,它们确实会在内存中获得它。
BSS 是以可执行(或 ELF)格式定义的占位符。所以它不占用磁盘空间,而只是指定链接器或加载器应该分配哪些内存区域。
具体操作取决于操作系统。由于您指的是 ELF,我认为它是用于嵌入式系统的。如果您为 ROMmable 代码构建,您的链接器 cmd 文件会将 BSS 映射到静态地址区域。
如果您为操作系统(即 Linux)构建,来自操作系统的加载程序将执行重定位传递,其中它将所有以可执行格式标记为相对的位置映射到内存中的物理或逻辑位置。
因为您提到总是看到相同的值,这表明该过程对于您的系统是可重复的。当您更改链接器文件(即地址区域)、链接顺序(即模块将以不同的顺序分配空间)或操作系统时,预计会看到更改。
无论您是否使用 BSS 值,地址对于您运行的进程都将保持不变。
就像代码和堆栈部分(以及任何其他 ELF 可能有)一样,该 BSS 部分在进程地址空间中被赋予了一个内存块。到了那里,他们哪儿也不去。加载器安排事情然后调用进程入口点。