装载(load)

    所谓装载(load),指将一个程序从硬盘搬移到RAM,跳转过去执行的过程。如果不考虑动态链接的话,装载过程并不复杂。这篇文档的作用,就是阐明Linux和Windows究竟是如何将一个程序装载到内存中的。
    在Linux下,可执行文件的保存格式是ELF(Executable Linkable Format),而Windows下的可执行文件为PE(Portable Executable)。ELF和PE都源于COFF(Common File Format),因此非常类似。无论ELF还是PE,都以段(section)为基本单位存储程序(包括数据)。其实,这一点和直接用汇编语言写成的程序很像。汇编语言习惯于以段为单位组织程序。一个典型的汇编程序包含数据段、代码段和栈段。事实上,ELF和PE也包含数据段和代码段,但却不包含栈段,因为栈段由操作系统负责分配。另外,除了数据段和代码段外,ELF和PE还包含其它名目众多的段。在Ubuntu 14.04.1下,使用gcc version 4.8.2编译链接一个HelloWorld,会产生25个段。例如只读数据段,其中保存有由const关键词修饰的,已经初始化的全局变量或静态变量,也有作为printf()的参数的字符串;再如注释段,其中保存有调试相关的信息。操作系统的装载器负责将ELF/PE中必要的部分载入内存,然后跳转执行。
    从操作系统的角度看,不同程序(或称任务,或称进程)的本质区别在于它们使用相互独立的虚拟内存空间。因此,装载过程大体上分为三步:1. 建立虚拟内存空间;2. 将程序从硬盘拷入内存 3. 跳转执行。首先,建立虚拟内存空间可以通过建立页目录表与页表实现。第二,ELF和PE文件本身就是内存中程序的映像(除了.comment段),而ELF/PE文件到内存的映射关系被记录在ELF/PE文件中。ELF的段表表项中,域VMA就是该段在虚拟内存空间中的位置。PE文件的头部中,域image base指出整个映像文件在虚存中的基地址,而段表表项中的virtual address指相对于image base的偏移。加载器要在众多段中选择出需要加载的段(我也不清楚是哪些,不过应该因操作系统、编译链接环境而异),映射到内存。第三,程序的入口地址保存在ELF/PE头部。综上,ELF/PE文件完整保存装载所需的所有信息。
    另外,除了以上三个步骤外,加载器还要负责为程序建立、维护栈段,运行库负责为程序建立、维护堆。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值