程序执行过程
- 编译:将C语言转为汇编语言,多个
.c文件被编译成对应的.s文件。 - 汇编:将汇编语言转为机器语言,每个
.s文件被汇编成对应的.o文件。 - 链接:与库文件(如
libc.a)一起链接,生成可执行文件.out。 - 加载:操作系统将可执行文件加载到内存中,准备执行。
Compiler
- 分析语法语义
- 优化并生成汇编代码
Assembler
- 展开伪指令
- 生成机器码
- 生成符号表(symbol table)与重定位表(relocation table)
- 符号表:记录函数和变量的名称与地址的映射关系
- 重定位表:记录需要链接器填充地址的指令位置和类型。
例如
jal ra, printf记录这里需要修正printf的地址
Linker
- 将多个
.o文件中的text段(代码段)和data段(数据段)合并 - 解析符号表,找定义,匹配引用
- 重定位,将重定位表中的指令地址填充正确的地址
静态/动态链接:
- 静态链接:将所有库函数与用户代码一起编译成一个可执行文件,运行时不依赖外部库。
- 动态链接:在运行时加载库函数,生成的可执行文件较小,但运行时需要依赖外部库。
Loader
- 读文件头,决定程序指令和数据的大小
- 分配内存,加载指令和数据到内存
- 设置程序参数,初始化寄存器
- 跳转到程序入口点,开始执行