用户程序要在系统中运行,必须先将它装入内存,然后再将其转变为一个可以执行的程序,通常都要经过以下几个步骤: (1) 编译,由编译程序(Compiler)对用户源程序进行编译,形成若干个目标模块(Object Module); (2) 链接,由链接程序(Linker)将编译后形成的一组目标模块以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module); (3) 装入,由装入程序(Loader)将装入模块装入内存。
程序的装入有三种装入装入方式:1. 绝对装入方式(Absolute Loading Mode) 当计算机系统很小,且仅能运行单道程序时,完全有可能知道程序将驻留在内存的什么位置。此时可以采用绝对装入方式。用户程序经编译后,将产生绝对地址(即物理地址)的目标代码。 在编译时,知道程序将驻留在内存的什么位置→产生绝对地址的目标代码→将程序和数据装入内存。 不需要对程序和数据的地址进行修改,逻辑地址即物理地址。2. 可重定位装入方式(Relocation Loading Mode) 在多道程序环境下,编译程序不可能预知经编译后所得到的目标模块应放在内存的何处。 对于用户程序编译所形成的若干个目标模块,它们的起始地址通常都是从0开始的,程序中的其它地址也都是相对于起始地址计算的。 采用可重定位装入方式,它可以根据内存的具体情况将装入模块装入到内存的适当位置。3. 动态运行时的装入方式(Dynamic Run-time Loading) 可重定位装入方式并不允许程序运行时在内存中移动位置。然而,实际情况是,在运行过程中它在内存中的位置可能经常要改变,此时就应采用动态运行时装入的方式。 把地址转换的工作推迟到程序执行时进行。 装入后的所有地址都仍是相对地址。 这种方式需要重定位寄存器的支持。
程序的链接:
1. 静态链接(Static Linking)方式 在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的装配模块,以后不再拆开。将几个目标模块装配成一个装入模块时,须解决一下两个问题: (1) 对相对地址进行修改。 (2) 变换外部调用符号。
2. 装入时动态链接(Load-time Dynamic Linking) 指将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的链接方式。即在装入一个目标模块时,若发生一个外部模块调用事件(即装入系统发现目标模块中有对其他目标模块的调用),将引起装入程序去找出相应的外部目标模块,并将它装入内存,还要修改目标模块中的相对地址。装入时动态链接方式有以下优点:(1) 便于修改和更新:由于各目标模块是分开存放的,所以要修改或更新各目标模块是件非常容易的事。 (2) 便于实现对目标模块的共享:OS很容易将一个目标模块链接到几个应用模块上,实现多个应用程序对该模块的共享。