三探·模块拼装思想(静态链接)

来源:互联网 发布:淘宝联盟找优惠券 编辑:程序博客网 时间:2024/05/16 01:41

程序设计的模块化是程序员一直追求的目标,因为当一个系统非常复杂的时候,我们就不得不把一个复杂的系统逐步分割成晓得系统以达到各个突破的目的。一个复杂软件的开发过程也如此;首先把每个源代码模块独立地编译,然后按照需要将他们“组装”起来,这个组装过的过程就是我们通常说的链接的过程。链接的主要内容就是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接。

链接器所做的工作和程序员“人工调整地址”本质上是一样的。只不过现代高级语言的诸多特性和功能,使得编译器、链接器更为复杂,功能更为强大。但是从原理上面讲,她的工作无非就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括地址和空间分配(Address and Storage Allocation)、符号决议(Symbol Resolution)和重定位(Relocation)等这些步骤。

1.静态链接过程示意图


每个模块的源代码文件(如.c文件)经过编译器编译成目标文件(Object File,一般扩展名为.o或.obj文件)。目标文件与库(libarary)一起链接形成最终的可执行文件。而最常见的库就是运行时库(Runtime Library)。他是支持程序运行的基本函数集合。库其实是一组目标文件的包,就是一些最常用的代码编辑成目标文件后打包存放
:对于object文件没有一个很合适的中文名称,我们把它称为中间目标文件还是比较合适的,简称为目标文件。

2.链接的内部执行过程

现代的链接和编译过程也并非想想中的那么复杂,他还是一个比较容易理解的概念。比如我们在程序模块main.c中使用另外一个模块func.c中的函数foo()。我们在main.c模块中每一处调用foo的时候都必须明确知道foo函数的地址,所以链接器暂时把这些调用foo函数的指令的目标地址搁置,等待最后链接的时候由链接器区将这些指令的目标地址修正。如果没由链接器,那么我们就必须手动的修改,即填入正确的foo函数地址。
这里我们需要注意一点的是:当func.c模块被重新编译,foo函数的地址有可能改变时,那么我们在main.c中所有使用到的foo地址指令将要全部重新调整。如果没由链接器,那么这一项工作对于程序员来说就是一个噩梦!使用链接器,我们可以直接引用其他模块的函数和全局变量而不用知道他们的地址!!!(这对程序员来说,无疑是个Big Surprise)因为连接器在链接的时候,会根据我们程序中所引用的foo符号,自动去相应的func.c模块中查找foo地址,然后将main.c模块中所有引用到foo的指令重新进行修改,让他们的目标地址为真正的foo函数地址。这就是静态链接的最基本的过程和作用。

1 0
原创粉丝点击