首页 > 代码库 > 程序的装入重新定位

程序的装入重新定位

  

程序的装入
为了阐述上的方便,我们先介绍一个无需进行链接的单个目标模块的装入过程。该目
标模块也就是装入模块。在将一个装入模块装入内存时,可以有绝对装入方式、可重定位
装入方式和动态运行时装入方式,下面分别简述之。
第四章 存 储 器 管 理 ·119·
1.绝对装入方式(Absolute Loading Mode)
在编译时,如果知道程序将驻留在内存的什么位置,那么,编译程序将产生绝对地址
的目标代码。例如,事先已知用户程序(进程)驻留在从 R 处开始的位置,则编译程序所产生
的目标模块(即装入模块)便从 R 处开始向上扩展。 绝对装入程序按照装入模块中的地址, 将
程序和数据装入内存。装入模块被装入内存后,由于程序中的逻辑地址与实际内存地址完
全相同,故不须对程序和数据的地址进行修改。
程序中所使用的绝对地址,既可在编译或汇编时给出,也可由程序员直接赋予。但在
由程序员直接给出绝对地址时,不仅要求程序员熟悉内存的使用情况,而且一旦程序或数
据被修改后,可能要改变程序中的所有地址。因此,通常是宁可在程序中采用符号地址,
然后在编译或汇编时,再将这些符号地址转换为绝对地址。
2.可重定位装入方式(Relocation Loading Mode)
绝对装入方式只能将目标模块装入到内存中事先指定的位置。在多道程序环境下,编
译程序不可能预知所编译的目标模块应放在内存的何处,因此,绝对装入方式只适用于单
道程序环境。在多道程序环境下,所得到的目标模块的起始地址通常是从 0 开始的,程序
中的其它地址也都是相对于起始地址计算的。此时应采用可重定位装入方式,根据内存的
当前情况,将装入模块装入到内存的适当位置。
值得注意的是, 在采用可重定位装入程序将
装入模块装入内存后, 会使装入模块中的所有逻
辑地址与实际装入内存的物理地址不同,图 4-3
示出了这一情况。例如,在用户程序的 1000 号
单元处有一条指令 LOAD 1,2500,该指令的功
能是将 2500 单元中的整数 365 取至寄存器 1。
但若将该用户程序装入到内存的 10000~15000
号单元而不进行地址变换, 则在执行 11000 号单
元中的指令时,它将仍从 2500 号单元中把数据
取至寄存器 1 而导致数据错误。由图 4-3 可见,
正确的方法应该是将取数指令中的地址 2500 修
改成 12500,即把指令中的相对地址 2500 与本程序在内存中的起始地址 10000 相加,才得
到正确的物理地址 12500。除了数据地址应修改外,指令地址也须做同样的修改,即将指令
的相对地址 1000 与起始地址 10000 相加,得到绝对地址 11000。通常是把在装入时对目标
程序中指令和数据的修改过程称为重定位。又因为地址变换通常是在装入时一次完成的,
以后不再改变,故称为静态重定位。
3.动态运行时装入方式(Dynamic Run-time Loading)
可重定位装入方式可将装入模块装入到内存中任何允许的位置,故可用于多道程序环
境;但这种方式并不允许程序运行时在内存中移动位置。因为,程序在内存中的移动,意
味着它的物理位置发生了变化, 这时必须对程序和数据的地址(是绝对地址)进行修改后方能
运行。然而,实际情况是,在运行过程中它在内存中的位置可能经常要改变,此时就应采
用动态运行时装入的方式。
LOAD 1,2500
365
LOAD 1,2500
365
10000
11000
12500
15000
5000
2500
1000
0
作业地址空间
内存空间
图 4-3 作业装入内存时的情况
·120· 计算机操作系统
动态运行时的装入程序在把装入模块装入内存后,并不立即把装入模块中的相对地址
转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存
后的所有地址都仍是相对地址。为使地址转换不影响指令的执行速度,这种方式需要一个
重定位寄存器的支持,我们将在 4.3 节中做详细介绍

程序的装入重新定位