1.预编译 .i
linux 命令:gcc -E main.c -o main.i
- 删除#define,并做文本替换
- #include递归展开头文件
- 处理预编译指令 #if #endif
- 删除注释
- 添加行号 文件标识
- 保留#pragma
2.编译 .s
linux 命令:gcc -S main.i -o main.s
- 词法分析
- 语法分析
- 语义分析
- 代码优化
- 生成汇编指令
3.汇编 .o
linux 命令:gcc -c main.s -o main.o
- 将汇编指令翻译成二进制
- 生成各个section
- 生成符号表
4.链接
linux 命令:gcc main.o -o main
- 合并所有文件的各个section,调整段大小及段的起始位置。合并符号表,进行符号解析,并给符号分配一个虚拟地址。
- 进行符号重定位,在使用符号的地方,全部替换成符号的虚拟地址。
汇编后的 .o 文件和链接后的 .o 文件有何不同
- 汇编程序生成的 .o 目标文件,并不会立即执行,因为原本.c 或者 .cpp 文件中可能还引用了另一个文件中定义的符号,或者调用了某个库文件中的函数。
- 链接的目的就是将这些文件对应的目标文件连接成一个整体,从而生成可执行的程序文件。
C语言中的强弱符号
一个项目可能有多个源文件,编译阶段都是每个文件单独编译的,可能在其他文件中存在强符号,所以没办法在编译期间确定具体的符号。因此将本文件的弱符号存放在COM块,而不是.bss段。
强符号:全局的已初始化的符号
弱符号:全局的未初始化的符号
强弱符号的选取规则:
- 两个强符号 编译报错
- 一个强符号 一个弱符号 选择强符号
- 两个弱符号 根据不同编译器处理方式不同
可扩展 objdump 和 readelf 的使用
1. man objdump
objdump - 显示二进制文件信息(.o 文件)
2. man readelf
readelf – 显示elf文件信息
LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、COFF(Common Object File Format 通用对象文件格式)、ELF(Executable and Linking Format 可执行和链接格式)。
. elf格式介绍
Executable and linking format(ELF)文件是Linux系统下的一种常用目标文件(object file)格式,有三种主要类型:
(1)适于连接的可重定位文件(relocatable file),可与其它目标文件一起创建可执行文件和共享目标文件 (.obj or .o)
(2)适于执行的可执行文件(executable file),用于提供程序的进程映像,加载的内存执行。
(3)共享目标文件(shared object file),连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件,动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。
(TL笔记复习)