程序编译的四个阶段?
基础知识 _每日一记(2)
1.什么是程序编译?
编译程序(Compiler,compiling program),也称为编译器,是指把用高级程序设计语言书写的源程序,翻译成等价的机器语言格式目标程序的翻译程序。
2.程序编译的四个阶段?
1.预编译(预处理):
- 预处理器(cpp)将所有的#define删除,并且展开所有的宏定义。
- 处理所有的条件预编译指令,比如#if、#ifdef、#elif、#else、#endif等。
- 处理#include预编译指令,将被包含的文件直接插入到预编译指令的位置。
- 删除所有的注释。
- 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
- 保留所有的#pragma编译器指令,因为编译器需要使用它们。
- 使用gcc -E hello.c -o hello.i命令来进行预处理, 预处理得到的另一个程序通常是以.i作为文件扩展名。
2.编译:
编译器做语法分析,词法分析,语义分析,产生汇编文件代码,以.s文件作为作为文件拓展名。
编译过程可分为6步:
- 词法分析:扫描器(Scanner)将源代的字符序列分割成一系列的记号(Token)。lex工具可实现词法扫描。
- 语法分析:语法分析器将记号(Token)产生语法树(Syntax Tree)。yacc工具可实现语法分析(yacc: Yet Another Compiler Compiler)。
- 语义分析:静态语义(在编译器可以确定的语义)、动态语义(只能在运行期才能确定的语义)。
- 源代码优化:源代码优化器(Source Code Optimizer),将整个语法书转化为中间代码(Intermediate Code)(中间代码是与目标机器和运行环境无关的)。中间代码使得编译器被分为前端和后端。编译器前端负责产生机器无关的中间代码;编译器后端将中间代码转化为目标机器代码。
- 目标代码生成:代码生成器(Code Generator).
- 目标代码优化:目标代码优化器(Target Code Optimizer)。
3.汇编:
将相关的.s文件翻译成机器语言,并将它保存在文件拓展名为.o的文件中。
4.链接:
链接(linking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。如我们新建了一个文件hello.c/hello.cpp,我们要用printf函数输出"hello world",printf函数存在于一个名为printf.o的单独预编译目标文件中。必须得将其并入到hello.o的程序中,链接器就是负责处理这两个的并入,结果得到hello文件,它就是一个可执行的目标文件。
特点:链接可以执行于编译时(compile time),也就是源代码被翻译成机器代码时;也可以执行于加载时(load time),也就是程序被加载到内存并执行时;甚至执行于运行时(run time),也就是由应用程序来执行。也就是由应用程序来执行。链接是由叫链接器(linker)的程序自动执行的。
意义:链接使得分离编译(separate compilation)成为可能,我们不用将一个大型的应用程序组织成一个巨大的源文件,而是可以把它分解成为更小、更好管理的模块,可以独立的修改和编译这些模块。当我们改变这些模块中的一个时,只需要简单的重新编译它,并重新链接应用,而不必重新编译其他文件。
部分转载自:https://zhuanlan.zhihu.com/p/476697014