linux 的汇编和链接

若main.c 为c语言文件, gcc -c main.c main.o  ;gcc main.o -o main

其中-c位目标文件, -0为可执行文件, -s 为汇编文件;


gcc main.o -o main 相当于

$ ld /usr/lib/crt1.o /usr/lib/crti.o main.o -o main -lc -dynamic-
linker /lib/ld-linux.so.2

也就是说,除了crt1.o之外其实还有crti.o,这两个目标文件和我们的main.o链接在一起生成可执
行文件main 。-lc表示需要链接libc 库,在第 1 节 “数学函数”讲过-lc选项是gcc 默认的,不用写,
而对于ld则不是默认选项,所以要写上。-dynamic-linker /lib/ld-linux.so.2 指定动态链接器
是/lib/ld-linux.so.2 。
那么crt1.o和crti.o里面都有什么呢?我们可以用readelf命令查看。在这里我们只关心符号表,如
果只看符号表,可以用readelf命令的-s选项,也可以用nm命令。
$ nm /usr/lib/crt1.o
00000000 R _IO_stdin_used
00000000 D __data_start
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
00000000 R _fp_hw
00000000 T _start
00000000 W data_start
                  U main
$ nm /usr/lib/crti.o
              U _GLOBAL_OFFSET_TABLE_
              w __gmon_start__
             00000000 T _fini
             00000000 T _init
U main 这一行表示main 这个符号在crt1.o中用到了,但是没有定义(U表示Undefined),因此需要
别的目标文件提供一个定义并且和crt1.o链接在一起。具体来说,在crt1.o中要用到main 这个符

号所代表的地址,例如有一条指令是push $符号main所代表的地址,但不知道这个地址是多少,所

以在crt1.o中这条指令暂时写成push $0x0 ,等到和main.o链接成可执行文件时就知道这个地址

是多少了,比如是0x80483c4,那么可执行文件main 中的这条指令就被链接器改成了push $0x80483c4 。

链接器在这里起到符号解析(Symbol 件)”我们看到链接器起到重定位的作用,这两种作用都是通过

修改指令中的地址实现的,链接器也是一种编辑器,vi和emacs 编辑的是源文件,而链接器编辑的是

目标文件,所以链接器也叫LinkEditor。T _start这一行表示_start这个符号在crt1.o中提供了定义,

这个符号的类型是代码(T表示Text)。我们从上面的输出结果中选取几个符号用图示说明它们之

间的关系:
图 19.3. C程序的链接过程
其实上面我们写的ld命令做了很多简化,gcc 在链接时还用到了另外几个目标文件,所以上图多画
了一个框,表示组成可执行文件main 的除了main.o、crt1.o和crti.o之外还有其它目标文件。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值