程序员—>编辑得到源代码—>编译得到目标模块—>链接装入模块—>装入内存中实际的物理地址
编译:将程序源代码编译成汇编代码
编译是读取源程序,进行词法和语法分析,将高级语言代码转换为汇编代码。
汇编。汇编器会将汇编代码文件翻译成为二进制的机器码。
链接:由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块
装入(装载):由装入程序将装入模块装入内存运行
链接器和加载器是由操作系统实现的程序。而编译器和汇编器则是由不同的编程语言自己实现的了。
链接的三种方式
- 静态链接:在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块)之后不再拆开。
直接在编译阶段就把静态库加入到可执行文件当中去。优点:不用担心目标用户缺少库文件。缺点:最终的可执行文件会较大;且多个应用程序之间无法共享库文件,会造成内存浪费。
-
装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式。
-
运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
- 不需要的不用进行链接
在链接阶段只加入一些描述信息,等到程序执行时再从系统中把相应的动态库加载到内存中去。优点:可执行文件小;多个应用程序之间可以共享库文件。缺点:需要保证目标用户有相应的库文件。
装入的三种方式(用三种不同的方法完成逻辑地址到物理地址的转换):
-
绝对装入
- 绝对装入:在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
- 只适用于单道程序环境
- 程序中使用的绝对地址,可在编译或汇编时给出,也可由程序员直接赋予。通常情况下都是编译或汇编时再转换为绝对地址。
-
静态重定位
- 编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的状况,将装入模块装入到内存适当的位置,将逻辑地址变为物理地址
- 特点:一个作业装入内存时,必须分配其要求的全部内存空间,一旦装入内存,在运行期间就不能再移动,也不能申请内存空间
-
动态重定位
- 编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行,需设置重定位寄存器
- 动态重定位时允许程序在内存中发生移动