linux静态链接学习笔记

对于我这位初学者而言,链接(linking)这个名词听着既熟悉又陌生。我知道基本上每一次运行都会包含链接操作,但又不知道链接具体又是如何做到的。所以我想理清一下这个内容。
链接(linking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并运行。链接可以执行于编译(compile)的时候,也就是在源代码被翻译成机器代码时;也可以执行于加载(load)的时候,也就是有应用程序来执行。早期计算机系统中,链接是手动执行的。现代系统中,链接是由叫做链接器(linker)的程序自动执行的。
无论是什么样的操作系统、ISA或者目标文件格式,基本的链接概念是通用的,细节可能不尽相同,但是概念是相同的。
下面,让我们在linux系统下做一些小测试。
main.c的代码:

int sum(int *a, int n);

int array[2] = {1, 2};

int main() 
{
    int val = sum(array, 2);
    return val;
}

sum.c的代码:

int sum(int *a, int n)
{
    int i, s = 0;
    
    for (i = 0; i < n; i++) { 
        s += a[i];
    }
    return s;
}        

在Linux系统下,输入命令:gcc -Og -o prog main.c sum.c
其中-o 命令能够生成目标文件,prog 是将目标文件重命名

由于main.c中没有打印函数,所以我在main.c文件中加了几行代码让返回结果能够打印输出。结果如下:
在这里插入图片描述
main.c 和sum.c文件经过翻译器生成 main.o和sum.o可重定位目标文件。再经过链接器(ld)生成被重命名为prog的完全链接的可执行目标文件。

这个过程可以通过用 -v选项运行gcc查看。
驱动程序首先运行C预处理器(cpp),它将C的源程序main.c翻译成一个ASCⅡ码的中间文件main.i:
cpp main.c /tmp/main.i
然后驱动程序运行C编译器(ccl),它将main.i 翻译成一个ASCⅡ汇编语言文件main.s:
ccl /tmp/main.i -Og -o /tmp/main.s
然后,驱动程序运行汇编器(as),它将main.s翻译成一个可重定位目标文件main.o:
as -o /tmp/main.o /tmp/main.s
驱动程序经过相同的过程生成sum。最后,它运行链接器程序ld,将main.o和sum.o以及一些必要的系统目标文件组合起来,创建一个可执行目标文件prog:
ld -o prog /tmp/main.o /tmp/sum.o
最后再运行可执行文件prog:
./prog

通过上述过程发现,目标文件有多种形式,实际上是有三种:可重定位目标文件、可执行目标文件和共享目标文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值