王道操作系统笔记,视频链接:3.1.1.3 进程的内存映像

进程的内存映像

  1. 用于讲解的代码程序例子:
#include <stdio.h>
#define X 1024   //宏定义的常量
int a=1;          //全局变量
const int b=2;    //常量
void main(){
    static int c=3; //静态变量
    int d=4;        //局部变量
    int *p = (int *)malloc(sizeof(int)*10);
    a = b+c+d;
    for (int i=0; i<10; i++){
        p[i] = X+i;
    }
    printf("Hello 研究生! \n");
...
}
  1. 假定的内存:
    • 32位系统指的是32个字节,
    • 所以进程虚拟地址空间为4GB,因为刚好是 2 3 2 2^32 232字节。
    • 图:
      内存图
  2. 在第2点的图中,高地址的部分(图中操作系统内核区)会用于存储操作系统的一些内核数据,比如:
    • 进程的PCB、页表
    • 操作系统的代码
      • 第二章中学的进程调度就属于操作系统的代码
  3. 例子中的程序属于用户程序,只能访问用户区的数据,不能访问操作系统内核区。
  4. 用户区域从最低的部分开始往上,分别用于存储:
    • ①只读代码/数据(紫色部分)
      • 程序代码正式运行前会经过编译、链接等一系列处理,
      • 代码被翻译为与之等价的机器指令,
      • 这些机器指令在程序运行过程中不会改变,所以属于只读代码,
      • 运行过程中只能读取,不能写入,所以存储在这个区域。
      • 还有一些比如C语言当中表示常量的const,这类不能被修改的变量也会被存储在这个区域。
      • PS:C语言的宏定义中不会在内存中专门分配存储空间,
        • 如代码示例的#define X 1024,编译器会在预编译阶段将X替换为1024,
        • 然后1024这个值会被隐含到程序指令当中,
        • 这种将常量直接放在指令中的寻址方式叫做立即数寻址。
          • 注意:如果数值太大导致指令“塞不下”,编译器则会将常量放入内存的只读数据段,通过地址访问——但这一般不影响我们理解宏的本质。
        • 但是这是计组的内容了,这里不细究,可以自己搜索看看。
        • 总之,宏定义不会存储在这一部分
    • ②读/写数据(绿色部分)
      • 结合C语言来说,就是全局变量和静态变量
        • 比如代码中的a,定义在main外,是全局变量
        • 代码中的c,用static关键字修饰,是静态变量
    • 以上两个部分,在进程启动时确定大小,固定不变
      • 因为这些部分本来就可以启动时确定
    • ③堆(heap)(蓝色部分)
      • 结合C语言来看,在C语言中,
      • 但凡用malloc和free两个函数去处理的那些数据就存储在堆当中。
      • 显然,这部分的大小是可以动态增加减小的,
      • 因为可以动态使用malloc和free
      • 对于32位系统来说,堆、读/写数据、只读代码/数据、未使用区四个部分最多为1GB
      • 也就是说,除去读/写数据、只读代码/数据、未使用区三部分,
      • 这1G剩下的空间可以全用于malloc和free
      • 64位系统给的空间更大,这里就不展开细聊
    • ④共享库的存储映射区(黄色部分)
      • 系统提供的库函数,比如print函数的代码,
      • 这些库函数的指令和代码就存储在这一部分,
      • 不同程序使用到的库函数不一样,用的越多,占用空间越多
      • 它从中间2GB的低地址部分往上
    • ⑤用户栈(Stack)(红色部分)
      • 程序由main函数进入,可能调用其他函数,
      • 每调用一层函数,就需要保存上一层函数的信息,
      • 同时需要开辟一个新的空间用于存储被调用函数的相关信息,
      • 所有的和函数调用相关的数据就存储在用户栈这一片区域当中。
      • 显然,这片区域也是会动态的增加或减少的。
      • 调用的函数层数越多,那么用户栈也会越大,
      • 函数中定义的局部变量以及函数调用的参数也存储在用户栈。
      • 它从中间2GB的高地址部分往下
  5. 第5点的图:
    进程的内存映像与代码对应
  6. 可能的考察形式:
    • 给一段C语言代码,询问对应的变量应该存储在哪一片区域当中

可能考法:根据C语言程序回答存储区域

可能考法

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐