简介
一个大的程序往往会分为多个源程序文件来编写,因而需要对多个源程序分别进行编译或汇编,来生成多个不同的目标文件(.o文件),这些目标文件包含指令、数据、和其他说明信息。
为了生成一个可执行文件,需要按照一定的格式将多个目标文件融合在一起。而这就是链接器最基本的作用。
目标文件与可执行文件对比
目标文件
root@000d3fada0b3:~/asm# objdump -d hello.o
hello.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: b8 01 00 00 00 mov $0x1,%eax
5: bf 01 00 00 00 mov $0x1,%edi
a: 48 be 00 00 00 00 00 movabs $0x0,%rsi
11: 00 00 00
14: ba 0e 00 00 00 mov $0xe,%edx
19: 0f 05 syscall
1b: b8 3c 00 00 00 mov $0x3c,%eax
20: 48 31 ff xor %rdi,%rdi
23: 0f 05 syscall
反汇编时,我们可以看到<_start>标签是没有分配地址的。
可执行文件
root@000d3fada0b3:~/asm# objdump -d hello
hello: file format elf64-x86-64
Disassembly of section .text:
00000000004000b0 <_start>:
4000b0: b8 01 00 00 00 mov $0x1,%eax
4000b5: bf 01 00 00 00 mov $0x1,%edi
4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi
4000c1: 00 00 00
4000c4: ba 0e 00 00 00 mov $0xe,%edx
4000c9: 0f 05 syscall
4000cb: b8 3c 00 00 00 mov $0x3c,%eax
4000d0: 48 31 ff xor %rdi,%rdi
4000d3: 0f 05 syscall
反汇编时,我们可以看到<_start>标签是分配了地址的。
链接器的作用
解析符号
解析文件中的变量、函数名称、语句等内容生成符号表。
符号表是一个结构数组,每个表项包含符号名、长度和位置信息等。
重新分配段(Section)空间
(ps: 不仅丑,还写错了。应该是.text)
每个目标文件(.o 文件)都有自己独立的.text段(Section)和.data段(Section)等空间。链接器将多个目标文件链接之后,生成一个新的可执行文件,需要对.text段以及.data段进行空间划分。
使用链接器的好处
模块化
可以将不同的源代码文件,由不同的人编写。之后再链接到一起。
提高效率
每个模块分开编译,只需要编译重新修改的源程序文件,之后再重新链接即可。
网友评论