一个C++源文件从文本到可执行文件的过程 :
一个C++程序从源码到执行文件,共有四个过程:预编译(预处理)、编译、汇编、链接:
1. 预编译(预处理): 预处理->.c(源文件)
-
将所有的#define删除,并且展开所有宏定义;
-
处理所有的条件预编译指令,如#ifdef;
-
处理#include预编译指令,将被包含的文件插入到预编译指令的位置;
-
过滤所有的注释;
- 添加行号和文件名标识;
2. 编译: 编译->.s/asm(汇编程序)
-
词法分析:将源代码的字符序列分割成一系列的记号;
-
语法分析:对记号进行语法分析,产生语法树;
-
语义分析:判断表达式是否有意义;
-
代码优化;
-
目标代码生成:生成汇编代码;
- 目标代码优化;
3. 汇编:汇编->.o/obj目标文件(二进制文件)
-
代码段:主要包含的是程序的指令,不可写,可读可执行;
- 数据段:存放程序中用到的各种全局变量或者静态数据。可读可执行;
4. 链接:链接->.exe可执行程序
-
合并各个.obj文件,合并符号表,解析符号表,判断是否重定义;
-
符号地址重定位;
-
生成.exe文件;
问题1:为什么要生成汇编,而不是直接从源文件编译成机器指令(二进制文件)?
-
首先,汇编语言作为机器指令的助记符,调试以及优化起来都会比较方便;
-
其次,汇编到机器指令的过程是由硬件完成的,是一个自动过程,让硬件来完成效率较高;
-
最后,如果要将源文件直接转换成机器指令,那么编译器编写者就必须要非常大数量的机器码,这是一个比较困难且低效的过程;
问题2:详细介绍从源文件经过编译到汇编语言的过程?
-
词法分析(Token):将源代码的字符序列分割成一系列的记号;
-
语法分析(syntax tree):对记号进行语法分析,产生语法树;
-
语义分析:判断表达式是否有意义;
-
代码优化;
-
目标代码生成:生成汇编代码;
-
目标代码优化;