编译链接过程:
-
预编译(预编译器处理如
#include
、#define
等预编译指令,生成.i
或.ii
文件) -
编译(编译器进行词法分析、语法分析、语义分析、中间代码生成、目标代码生成、优化,生成
.s
文件) -
汇编(汇编器把汇编码翻译成机器码,生成
.o
文件) -
链接(连接器进行地址和空间分配、符号决议、重定位,生成
.out
文件)
目标文件存储结构:
段 |
功能 |
File Header |
文件头,描述整个文件的文件属性(包括文件是否可执行、是静态链接或动态连接及入口地址、目标硬件、目标操作系统等) |
.text section |
代码段,执行语句编译成的机器代码 |
.data section |
数据段,已初始化的全局变量和局部静态变量 |
.bss section |
BSS 段(Block Started by Symbol),未初始化的全局变量和局部静态变量(因为默认值为 0,所以只是在此预留位置,不占空间) |
.rodata section |
只读数据段,存放只读数据,一般是程序里面的只读变量(如 const 修饰的变量)和字符串常量 |
.comment section |
注释信息段,存放编译器版本信息 |
.note.GNU-stack section |
堆栈提示段 |
目标文件--已经编译后的可执行文件格式,只是还没有经过链接的过程,其中有些符号或者有些地址还没有调整。
可执行文件(Windows 的 .exe
和 Linux 的 ELF
)、
动态链接库(Windows 的 .dll
和 Linux 的 .so
)、
静态链接库(Windows 的 .lib
和 Linux 的 .a
)都是按照可执行文件格式存储(Windows 按照 PE-COFF,Linux 按照 ELF)
目标文件格式:
-
Windows 的 PE(Portable Executable),或称为 PE-COFF,
.obj
格式
-
Linux 的 ELF(Executable Linkable Format),
.o
格式
-
Intel/Microsoft 的 OMF(Object Module Format)
-
Unix 的
a.out
格式
-
MS-DOS 的
.COM
格式