多道程序环境下,程序是并发执行的,所以要使程序运行,必须先为之创建进程,而创建进程的第一件事就是将程序和数据装入内存
即
下面开始将程序“链接”和“装入”的具体情况:
源程序经过编译后,得到一组目标模块,再利用“链接程序”将这组目标模块链接起来,形成一个完整的装入模块(即可执行文件)
如下图:源程序编译后得到三个目标模块A、B、C,长度分别为L、M、N,链接后形成右侧的装入模块:
链接时需要做两个工作:
Ø 相对地址进行修改(变化以后还是相对地址),地址都变为相对最上层模块的起始地址来计算。
Ø 变化外部调用符号,如CALL B------> JSR“L”
CALL B为调用B模块,JSR“L”为跳转到L行
链接前A和B为两个不同的模块,在A模块中想执行B模块,要使用调用(CALL)语句;链接后A和B为同一模块,若想达到同样地效果,只需在本模块中使用跳转语句(JSR)跳转到想执行的地方即可。
即将链接好的模块装入内存
用户程序编译为目标模块后,会对每个模块内部(程序数据等)进行编址,此时编好的地址叫做逻辑地址或相对地址(下面的绝对装入方式除外),都是相对于本模块的起始地址(一般从0开始)计算的。进行链接后某些模块的相对地址会发生变化,地址都变为相对于装入模块的起始地址进行计算。
通常将内存的实际地址称为物理地址
Ø 绝对装入方式
Ø 可重定位装入方式(静态重定位)
Ø 动态运行时装入方式(动态重定位)
程序编译时,如果知道程序将驻留在内存的什么位置(起始地址),那么编译生成的目标代码,将采用绝地地址进行编址,即起始地址不从0开始,从上面所知的内存起始地址开始编址。
例如:事先已知用户程序(进程)驻留在从1000号单元处开始的位置,则编译程序所产生的目标模块(即装入模块)便从1000处开始向上扩展:
由于采用的是绝对地址,所以将装入模块直接装入内存即可,无需进行地址变换。
Ø 出现:
编译时将程序装入指定的内存空间,必须需要程序员熟悉内存的使用情况
绝对装入方式只能将目标模块装入到内存中事先指定的位置。而在多道程序环境下,编译程序不可能预知所编译的目标模块应放在内存的何处
可重定位方式可根据内存的当前情况,将装入模块装入到内存的适当位置
Ø 原理:
源程序编译生成的目标模块都采用相对地址进行编址,即每个模块都从0开始编址,当然链接后的模块也采用相对地址编址
将装入模块装入内存后,模块中的程序和数据等,在内存中都将具有一个物理地址,此物理地址是相对于内存的起始地址进行编址的,所以与原先模块中的逻辑地址(相对于模块的起始地址进行编址)不同,所以为了得到物理地址需要对逻辑地址进行改变。而此地址变化的过程就叫做重定位,又因为地址变换通常是在装入时一次完成的,以后不再改变,故称为静态重定位。如下图:
只是把相对地址到绝对地址的转换推迟到程序真正执行时才进行