大致的理解如下,不一定正确,确认后会更新:
按照一般的步骤,用户程序在执行前会经历以下几个步骤:
- 编译汇编
- 链接(将编译出来的模块和其他引用了的模块合并)
- 加载(从硬盘加载到内存中)
- 执行(在内存中执行)
动态加载和动态链接是打破以上所描述的常规行为的。
动态加载¶
硬盘上存储了一个已经生成好的目标模块,但是这个目标模块是由许多子程序组成的。每时每刻,不一定所有的子程序都需要在内存中,所以,在使用到相应子程序时再把其加载到内存中来使用,这要求用户在编写程序时合理地编写子程序,不需要操作系统提供特别的支持。
动态链接¶
它与动态加载的概念相似,但是,它不是将加载延迟到了执行时,而是将链接延迟到执行时。主要的问题就在于理解这句话。对于动态链接,磁盘上存储着的目标模块中包含着一部分它并未链接的模块(但是它迟早要用,所以动态链接嘛~)。而使用动态加载技术时,你动态加载的模块是经过链接之后的,也就是该模块已经结合了所有它会用到的模块,只是在你程序的不同地方使用了,所以在不同的地方动态加载需要的代码。
动态链接的实现是依赖于存根(stub)的,目标模块中在使用需要动态链接的模块的地方使用存根来代替,存根能够指出如何装入以及装入后的程序在内存的哪。
动态链接的好处在于多个程序使用到了一个相同的模块时,不需要将该模块都像常规步骤或者动态加载那样合并到目标模块中,而是在执行时再动态链接,这样在内存中就只用存在一份该模块的代码了,即实现了共享库。