程序的编译,链接,运行和地址映射

1.在x86体系32位linux内核/操作系统下:
每一个进程在运行的时候,系统会为其分配一个以上构造的4G的虚拟地址空间:
3G为用户空间(私有)1G为内核空间(共享)
程序的编译,链接,运行和地址映射
代码段:存放程序的执行代码,大小在运行前已经确定,也包含一些只读的常数变量,例字符串常量等。
数据段:存放程序中已初始化的全局变量(静态分配内存)。
堆区:用于存放进程运行中被动态分配的内存段,大小不固定,可动态扩张或缩减。
      当进程调用malloc等函数分配内存,新分配的内存被动态添加到堆
      当利用free等函数释放内存时,内存从堆中剔除
栈区:用于存放程序临时创建的局部变量,即函数括弧"{}"中定义的变量。
      函数被调用时,其参数也会被压入发起调用的进程栈中,并且调用结束后,函数的        返回值也会被存放回栈中。(由操作系统分配,内存的申请和回收都有OS管理)

2.编译过程
程序的编译,链接,运行和地址映射.o/.obj文件为什么不能运行?
.o文件符号表里的符号,还没分配地址

3.链接过程
程序的编译,链接,运行和地址映射
(1)所有.o文件的段进行合并,其中包含合并符号表,进行[符号解析]
     解析正确,给符号表的符号分配虚拟地址
(2)进行[符号重定向] --> 把它们都替换成正确的虚拟地址
     -->exe(Windows)
          elf(Linux)
符号解析:未定义的符号,找到其定义的地方
运行时:代码段、数据段
        不用符号表段(因为有了正确的地址,要不要都无所谓)

4.IA32体系虚拟地址映射
程序的编译,链接,运行和地址映射
为什么不直接分配物理内存?
如果直接分配物理内存,有可能最终分配的地址被别人占用了
因为不知道哪块物理内存空闲。
程序的编译,链接,运行和地址映射
第1次页面映射一定失败(在操作系统里)-->缺页异常
怎么解决?  分配相应的物理内存
缺页异常处理完成之后-->重启地址映射-->成功