什么是静态链接
代码经过编译生成目标文件后的下一步是将多个目标文件链接成一个可以执行文件。
将多个目标文件链接成一个可执行文件的过程称为静态链接。
目标文件对于外部符号的处理
单个源文件编译中当引用到外部文件的变量或者函数时(这些外部函数与变量也称为外部符号),会暂时将引用到地址以伪地址代替,等待链接时将真正引用的地址替换上。
以两个文件hello.c和world.c为例子。hello.c引用了两个外部变量,一个为系统标准输出函数printf,一个为全局变量globalInt。
//hello.c
#include <stdio.h>
extern int globalInt ;
int main()
{
int b = doubleNumber(globalInt);
return b;
}
//world.c
int globalInt = 4;
int doubleNumber(int a)
{
return a * a;
}
使用-c参数编译
gcc -c hello.c world.c
hello.c 与world.c 并分别输出目标文件,hello.o和world.o
再将hello.o反编译成汇编代码objdump -d hello.o
将world.o反编译成汇编代码objdump -d world.o
hello.o: 文件格式 elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # e <main+0xe>
e: 89 c7 mov %eax,%edi
10: b8 00 00 00 00 mov $0x0,%eax
15: e8 00 00 00 00 callq 1a <main+0x1a>
1a: 89 45 fc mov %eax,-0x4(%rbp)
1d: 8b 45 fc mov -0x4(%rbp),%eax
20: c9 leaveq
21: c3 retq
这里需要留意两个行命令
1. 8: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # e <main+0xe>
这条指令的作用是将全局变量globalInt传入doubleNumber作为参数。命令为将相对rip位置为0的内存区域,传送至eax中。 其中8b05为mov的命令码,00000000为地址。 <