编译和连接-可执行文件的装载与进程

Published: 10 Jul 2013 Category: 编程

当我们需要执行一个可执行文件时,必须将它装载到内存以后才能被CPU执行,同时操作系统会为其运行一个进程,同时进程存在一个虚拟地址空间,可执行文件与虚拟地址空间存在一种映射关系。

进程虚拟地址空间

程序是一个静态的概念,他是一个指令集合文件。而进程是一个动态的概念,他是程序运行时的一个过程和操作系统管理的结构。

每个程序运行以后,他都拥有自己独立的虚拟地址空间,这个空间的大小由计算机的硬件决定(硬件寻址空间),如32位的计算机的虚拟地址空间为4G。

装载的方式和过程

程序执行时所需要的指令和数据必须在内存中才能正常运行,如果仅仅是将全部指令和数据都放入内存,物理内存的数量往往不够。由于程序运行的局部原理,我们可以将常用的驻留内存,其他的放在磁盘中,使用时再去磁盘中取。

一般解决这个问题的方法是页映射方法,对内存的使用基于页进行分配,操作系统通过一个页目录的结构对内存进行管理。关于页表的问题可以参考操作系统相关书籍。

进程的建立过程:

  • 创建一个独立的虚拟地址空间。不需要创建物理空间,只需要创建虚拟空间与物理空间的映射函数,一般是一个页目录。
  • 读取可执行文件头,并且建立虚拟空间与可执行文件的映射关系。文件头里面有可执行文件的相关信息,这样当需要访问某一页而这一页不在物理空间,就可以通过页错误去磁盘中的可执行文件中查找。
  • 将CPU的指令寄存器设置为可执行文件的入口地址,启动运行。文件头中有这个入口地址信息。

进程虚存空间分布

在执行文件中,常常有非常多的段,如果每个段在内存中都映射为一个段,因为每个段都要进行页的对齐,那将会浪费非常多的碎片空间。因此,操作系统根据访问权限将段合并为相应的segment,段根据访问权限可分为三类:可读可执行段(如代码段)、可读可写段(数据段和bbs段)、只读数据段(常数段、字符串段等)。同时考虑堆和栈,进程虚拟空间如下所示:

Linux将进程虚拟空间中的一个段叫虚拟内存区域(VMA,Virtual Memory Area);Windows中叫这个虚拟段。

进程虚拟地址空间概念总结:

  • 操作系统通过给进程空间划分出一个个VMA进行管理进程的虚拟空间;
  • 基本原则是将相同权限、相同映像文件的映射成一个VMA;
  • 一个进程基本上可分为四类VMA区域:
    • 代码VMA:只读、可执行;有映像文件。
    • 数据VMA:权限可读写、可执行;有映像文件。
    • 堆VMA:权限可读写、可执行;无映像文件;向上扩展。
    • 栈VMA:可读写、不可执行;无映像文件;向下扩展。