一、基础概念:预处理、编译、汇编、链接 四阶段
- 预处理阶段:读取源文件(源代码),对其中的伪指令和特殊符号进行处理,并删除注释,添加行号。.c/.cpp文件生成 .i文件
- 编译阶段: 将高级语言翻译成汇编语言,以及检查代码语法规范。.i文件生成 .s文件
- 汇编阶段: 将汇编语言转换为机器语言,并生成目标文件(二进制文件)。.s文件生成 .o文件
- 链接阶段: 将一个或多个目标文件链接在一起,生成可执行文件。.o文件生成 .exe文件
其中预处理、编译、汇编三个阶段可统称为编译,即一般说的“编译”是包括了这个三个阶段。
二、深入理解
预处理阶段:什么是伪指令和特殊符号?
伪指令:一般以 # 开头的指令,如常见的宏定义、条件编译指令、头文件等。
- 宏定义:如 #define NAME XieY。预处理时就会将程序中所有的NAME替换成XieY,除字符串常量"NAME"外;也可用
#undef取消宏定义,这样在 #undef后面的 NAME将不再被替换。 - 条件编译指令:#ifdef #else #endif。预处理时会根据条件过滤掉不必要的代码。
- 头文件:#include <fileName> 或 #include “fileName”。预处理时会将头文件中的定义都放到其所生成输出的文件中,以供后续编译使用。
- 特殊宏:如__FILE__(当前文件名)、__TIME__(当前时间)、__LINE__(当前行号)。预处理时会解释这类特殊宏的含义。
注意:预处理的工作就是“替换”,文件本身还是 .c/.cpp文件,只是没有了宏、条件编译指令、头文件等。
编译阶段:词法分析、语法分析、语义分析。
- 词法分析:按照词法规则去扫描字符串,进行对应的分割、记录。
- 语法分析:按照语法规则解析词法分析出来的对象。
- 语义分析:检查语句是否合法,是否有意义。有静态和动态语义,编译器只能分析静态语义。
- 静态语义:通常包括声明与类型的匹配,类型的转换。
- 动态语义:只有在运行期才能确定的语义。典型的就是检查除数不能为0。
注意:编译的工作就是“检查”。在所有指令都符合规则后会将预处理后的代码转换成汇编代码。
汇编阶段:经过编译得到的汇编代码必须经过汇编程序的汇编转换成相应的机器指令,生成目标文件后,方可被机器执行。
- 目标文件由段组成。通常一个目标文件中至少有两个段:
- 代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
- 数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。