操作系统静态链接、装入时动态链接和运行时动态链接方式的比较

操作系统中实现链接的方法有三种:静态链接、装入时动态链接和运行时动态链接。连接程序的功能,是将经过编译或汇编后所得到的一组目标模块以及它们所需要的库函数,装配成一个完整的装入模块。链接之前与链接之后,都是逻辑地址!

(1) 链接的含义

连接程序的功能,是将经过编译或汇编后所得到的一组目标模块以及它们所需要的库函数,装配成一个完整的装入模块。链接之前与链接之后,都是逻辑地址。

(2) 链接的类型

实现链接的方法有三种:静态链接、装入时动态链接和运行时动态链接。

① 静态链接

图5.2.2示出了经编译后所得到的三个目标模块A、B、C,他们的长度分别为 L、M、N。在模块A中,有一条语句CALL B,用于调用模块B。在模块B中,有一条语句CALL C, 用于调用模块C。B和C都属于外部调用符号,在将这几个目标模块链接装配成一个装入模块时,需要解决以下两个问题:

● 对相对地址进行修改

通常由编译程序产生的所有目标模块,其起始地址都为0,每个模块中的地址都是相对于0的。在链接成一个装入程序后,模块B和C的起始地址不再是0,而是L和L+M,此时需修改B和C中的相对地址,即模块B中的所有相对地址加上L,模块C中的相对地址都加上L+M。

● 变换外部调用符号

即将每个模块中所用的外部调用符号,都变换为相对地址,如把B的起始地址变换为L;C的起始地址变换为L+M,如图5.2.2(a)所示。这种先进行链接所形成的一个完整的装入模块,又称为可执行文件。通常都不要拆开它,要运行时可直接将它装入内存。这种事先进行链接,以后不再拆开的链接方式,称为静态链接方式。

操作系统静态链接示意图

② 装入时动态链接(Load-Time Dynamic Linking)

用户源程序经编译后所得到的目标模块,是在装入内存时,边装入边链接的.即在装入一个目标模块时,若发生一个外部模块调用,将引起装入程序去找出相应的外部目标模块,并将它装入内存,还要按照图所示的方式来修改目标模块中的相对地址。装入时动态链接方式有以下优点:

● 便于软件版本的修改和更新

在采用装入时动态链接方式时,要修改或更新各个目标模块,是件非常容易的事,但对于经静态链接以装配在一起的装入模块,如果要修改或更新其中的某个目标模块时,则要求重新打开装入模块,这不仅是低效的,而且有时是不可能的。

● 便于实现目标模块共享

若采用装入时动态链接方式,OS能够将一个目标模块链接到几个应用模块,即实现多个应用程序对该模块的共享;然而,采用静态链接方式时每个应用模块都必须含有该目标模块的拷贝,否则无法实现共享。

③ 运行时动态链接(Run –Time Dynamic Linking)

虽然前面所介绍的动态装入方式,可将一个装入模块装入到内存的任何地方,但装入模块的结构是静态的,它主要表现在两个方面:一是在进程的整个执行期间,装入模块不改变;再者是每次运行时的装入模块都是相同的。实际上,在许多情况下,每次要运行的模块可能是不相同的,但由于事先无法知道

本次要运行哪些模块,故只能是将所有可能要运行到的模块,在装入时全部链接在一起,是每次执行时的装入模块是相同的。显然这是低效的。因为这样,在装入模块的运行过程中,往往会有某些目标模块根本就不运行。比较典型的例子是错误处理模块,如果程序在整个运行过程中,都不出现错误,便不会用到该模块。

能有效的改变这种情况的链接方式,是最近几年流行起来的运行时动态链接方式。这种链接方式,可将某些目标模块的链接,推迟到执行时才进行。即在执行过程中,若发现一个被调用模块尚未装入内存时,由OS去找到该模块,将它装入内存,并把它连接到调用者模块上。