链接是将各种各样代码和数据部门收集起来并组合成为一个单一文件的过程,这个文件可被加载(或被拷贝)到存储器并执行。链接可以执行于编译时,也就是在源代码被翻译成机器代码时;也可执行于加载时,也就是在程序被加载器加载的存储器并执行时;甚至执行于运行时,由应用程序来执行。
1 编译器驱动程序
考虑如下的两个源文件:main.c和swap.c。
main.c
void swap(); int buf[2]={1,2}; int main() { swap(); return 0; }
swap.c
extern int buf[]; int *bufp0=buf; int *bufp1; void swap() { int temp; bufp1=&buf[1]; temp=*bufp0; *bufp0=*bufp1; *bufp1=temp; }
大多数编译系统提供编译驱动程序,它代表用户在需要时调用语言预处理器、编译器、汇编器和链接器。
例如:
gcc -02 -g --o p main.c swap.c
驱动程序首先调用C预处理器(cpp),它将C源程序main.c翻译成一个中间文件main.i:
cpp [other arguments] main.c /tmp/main.i
接下来,驱动程序运行C编译器(cc1),它将main.i翻译成一个汇编语言文件main.s
cc1 /tmp/main.i main.c -02 [other arguments] -o /tmp/main.s
然后,驱动程序汇编器(as),它将main.s翻译成一个可重定位目标文件main.o:
as [other arguments] -o /tmp/main.o /tmp/main.s
驱动程序经过相同的过程生成swap.o。最后,它运行链接器程序ld,将main.o和swap.o以及一些必要的系统目标文件组合起来,创建一个可执行目标文件p:
ld -o p [system object files and args] /tmp/main.o /tmp/swap.o
要运行可执行文件p,我们只需要输入 ./p
外壳调用操作系统中一个叫做加载器的函数,它拷贝可执行文件p中的代码和数据到存储器,然后将控制转移到这个程序的开头。
2 静态链接
时间: 2024-09-28 20:12:10