Linux进程的内存空间布局

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_37653144/article/details/82978929

       此文也可看作是Linux下C程序的内存空间布局(虚拟地址),因为在Linux下的C编译器本质上也是一个进程,编译器再强大也得在操作系统的保护模式下运行。

内存空间布局

       在Linux中,进程的内存空间按低地址到高地址的顺序分为:代码段text、数据段data、bss段、堆、栈和内核数据区(命令行参数和环境变量等)。如下图所示:

       从C程序的角度来说,低地址的三块内存区域由编译器和链接器规划地址空间,在程序被操作系统加载之前它们地址就固定了。堆和栈是可增长的,它们的增长方向相对,堆向上增长,栈向下增长。

       C程序的处理过程大体分为4个阶段:预处理、编译、汇编、链接。在汇编语言中,伪指令section和segment的作用相同,都是人为地将代码划分为逻辑块。但在程序处理种这两者不同:在汇编阶段,编译器会将汇编源程序中用section和segment关键字进行逻辑划分的指令或数据区域编译成节(section),生成在目标文件中;而segment则是链接器将目标文件中属性相同的多个section合并后的section集合,并生成可执行文件。内存中的数据段、代码段就是指合并后的segment。       

       对于操作系统,它只关心程序中这些节的属性是什么,因为它在分配内存时要为这些段分配合适的段描述符和段选择子。按照属性来划分节,大致上有三种类型。

       (1)可读写的数据,如数据节.data和未初始化数据节.bss

       (2)可读可执行的数据,如代码节.text和初始化代码节.init

       (3)只读数据,如只读数据节.rodata(一般情况下字符串就存储在此)

       划分好节后,相同属性的节就被合并为段了。

bss

       bss全称是Block Started by Symbol,bss通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是:可读写的,在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了。

       text段是代码段,里面存放的是程序的指令,data段是数据段,里面存放的是程序中运行时的数据,它们的共同点是都存在于程序文件中,也就是在文件系统中存在。而bss并不存在于程序文件中,它仅存在于内存中,其实际内容是在程序运行过程中才产生的。程序文件中仅在elf头中有bss的虚拟地址、大小等相关记录,这通常是由链接器来处理的,对程序运行并不重要。bss的作用在于为那些未初始化的全局变量和静态变量预留内存空间。在链接阶段,bss节会与数据节一起被划分到数据段中。

                                                                                                                本文部分内容摘自《操作系统真象还原》

猜你喜欢

转载自blog.csdn.net/qq_37653144/article/details/82978929