1. 将每个源代码独立编译之后,需要将他们“组装”起来,该过程便是链接。链接主要的工作就是将各个模块之间相互引用的地方处理好,使各个模块之间能够正确的衔接。

  2. 链接的过程主要包括了地址和空间分配、地址绑定和重定位等操作。

  3. 最基本的链接过程如下,每个模块的源代码文件(.c)->(.o)->(.out);

    wKiom1SRTgqCyerBAAFMXEAi_4o022.jpg

  4. 如果程序模块main.c中调用了func.c中的函数foo(),因此每一次main.c中调用foo()时,必须要知道函数的地址,但是由于每个模块在编译时是独立编译,并不知道foo()函数的确切地址,那该怎么办呢?编译器会先把这些调用foo()的指令的目标地址搁置,等待链接的时候链接器去修改其目标地址;如果没有连接器的话,那我们需要手动将把调用foo的指令进行修改,如果fun.c模块重新编译的话,那么foo的地址有可能发生变化,那么需要重新调整其他模块中调用foo指令的目标地址,这将是程序员的噩梦,因此这些工作都交给了连接器来做,因为链接器在链接的时候会根据你引用的符号foo,自动的去func.c模块中查找foo的地址,然后将其他模块引用foo的指令重新修改,让它的目标地址为真正foo函数的地址。

  5. 在编译时,引用其他模块中的函数或者全局变量,本模块的响应指令的目标地址默认为0,先搁置不管,等连接的时候连接器会去修改它,该过程也别叫做重定位。