为什么汇编程序要将数据段(.data
/.bss
)和代码段(.text
)加载到不同的内存块中,而不是载入一个单独的内存块?
我的猜测是操作系统可以随意移动这些段或者对存储的数据类型进行内存优化。您有何想法?
为什么汇编程序要将数据段(.data
/.bss
)和代码段(.text
)加载到不同的内存块中,而不是载入一个单独的内存块?
我的猜测是操作系统可以随意移动这些段或者对存储的数据类型进行内存优化。您有何想法?
这不仅适用于汇编程序,也适用于操作系统的可执行文件格式,大多数操作系统决定将程序的各个部分分离成不同的节("segments")。
将可执行文件分成不同的节有几个好处,例如您提到的:
.bss:存储需要在程序启动时清零的内存信息。需要清零的内存是常见的,操作系统通常具有为分配清零内存而设计的特殊服务。如果您分配了一个1MB的全局数组,则无需在可执行文件中嵌入1MB的0- 您只需将该信息编码在.bss节中,操作系统将在程序启动时分配1MB。
.data:这是所有在程序启动时初始化为非零的数据。
.text:这是实际代码
还可以有许多其他节,例如包含引导代码的特殊节,需要运行以初始化程序但一旦运行就可以丢弃的节,或包含调试信息的节(除非您在调试器中运行程序,否则不需要将其加载到内存中)。另一个常见的节是只读数据节:
.rodata:包含不可写数据,例如程序中的所有字符串或常量数据。
此外,CPU可以对内存应用保护,例如可读/可写/可执行内存。将不同的节分开允许轻松地应用这些内存保护。例如,代码需要是可执行的,但是将数据设置为可执行可能不是一个好主意。只读节也可以更容易地在其他进程之间共享,代码和只读内存节可以在程序的多个实例之间共享。如果文本节的某些部分需要交换出来,它们可以直接丢弃,因为它们已经驻留在可执行文件本身中,而数据/bss节不能,则必须将它们交换到特殊的交换区域。