为什么汇编程序将段(.data
/ .bss
和.text
)加载到单独的内存块中,而不是将数据和代码段加载到单个内存块中?
我的猜测是操作系统可以移动段或以某种方式优化内存以存储数据类型。思考?
答案 0 :(得分:11)
这不仅限于汇编程序,它是如何为您的操作系统的可执行格式布局的,并且大多数操作系统已经决定使用相当广泛的可执行文件格式,将程序的各个部分分成几个部分(“段”)
在各个部分中分离可执行文件具有几个优点,例如,你提到的那些:
.bss:存储有关在程序启动时需要归零的内存的信息。需要归零的内存很常见,操作系统通常有特殊的服务来分配内存,如果你碰巧分配1Mb的全局数组,你不需要在可执行文件中嵌入1Mb的0 - 你可以只需在.bss部分编码该信息,操作系统将在程序启动时分配1Mb。
.data:这是您在程序启动时初始化为零以外的所有数据。
.text:这是实际的代码
可以有更多部分,例如包含引导代码的特殊部分,需要运行以初始化程序,但一旦运行就可以丢弃,或者包含调试信息的部分(除非在调试器中运行程序,否则不需要加载到内存中)。另一个常见部分是只读数据部分:
.rodata:包含不可写的数据,例如程序中的所有字符串或常量数据。
此外,CPU可以对内存应用保护,例如可读/可写/可执行内存。具有单独的部分允许容易地应用这些存储器保护。例如。代码需要是可执行的,但让数据可执行可能是一个坏主意。 只读部分也可以更容易地在其他进程之间共享,代码和只读存储器部分可以在程序的多个实例之间共享。如果需要交换文本部分的部分,它们可以被丢弃,因为它们已经驻留在可执行文件本身中,而数据/ bss部分不能,它们必须被换出到特殊的交换区域。
答案 1 :(得分:3)
您通常可以逐段设置属性。例如,只读段允许您指定“只读”一次,并将只读数据放入该段,而不是逐个变量地指定只读。
答案 2 :(得分:0)
不,我认为您理解错误的细分概念不仅用于汇编,每种机器特定的高级语言(如C,C ++,Basic,Pascal等)都在内部使用细分。
因为每个C和C ++程序都是由GNU编译器编译成汇编语言的(在Ubuntu的情况下),编译器会将适当的data
放到适当的段中,GAS汇编器会将此汇编转换为目标代码字节。