1. 翻译环境和运行环境
首先来了解一下 ANSI C ,也就是 C 语言标准。在他的任何一种实现中,有两种不同的环境:翻译环境和执行环境。
- 翻译环境:此环境下,源代码将会被转换为可执行的机器指令。
- 执行环境:就是来实现代码执行的环境。
2. 翻译环境
翻译环境将源代码转换为可执行的机器指令主要是靠 编译 和 链接 两个过程,而编译又可以分为 预处理、编译、汇编。
图例:
下图为 gcc(观察更为细致) 下细分翻译环境的图例:
在 windows 下的目标文件的后缀是 .obj ,Linux环境下目标文件后缀是 .o 。
链接库:运行时的库或第三方库。
3. 编译
3.1 预处理(预编译)
在程序源代码被翻译为目标代码的过程中,生成二进制代码之前的过程。典型地,由预处理器(preprocessor) 对程序源代码文本进行处理,得到的结果再由编译器核心进一步编译。
预处理阶段对源代码进行的主要操作是:
- 删除所有注释。
- 删除所有 #define ,展开所有宏定义。
- 处理所有的条件指令(#if、#endif 等)。
- 处理 #include 预编译指令,将包含头文件的内容插入到指定位置(递归进行,头文件也可能包含其他内容)。
- 添加行号和文件标识,以便后续编译器生成调试信息。
- 保留所有的 #pragam 编译器指令。
3.2 编译
编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析、语法分析、语义检查和中间代码生成、代码优化、目标代码生成。主要是进行词法分析和语法分析,又称为源程序分析,分析过程中发现有语法错误,给出提示信息。
3.2.1 词法分析
词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
例如 C 中有 sum=6+8;这样一行代码,经过词法分析,就会被词法分析器(扫描器)读成:
语素 | 单词类型 |
---|---|
sum | 标识符 |
= | 赋值操作符 |
6 | 数字 |
+ | 加法操作符 |
8 | 数字 |
; | 语句结束标志 |
3.2.2 语法分析
语法分析是编译过程的一个 逻辑 阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等。
3.2.3 语义分析
语义分析是编译过程的一个逻辑阶段, 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查,进行类型审查。语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。(按照语法分析器识别的语法范畴进行语义检查和处理,产生相应的中间代码或目标代码)
相当于对照语言书写规范去审查,不符合则编译程序会报告相关错误。
3.3 汇编
把汇编语言书写的程序翻译成与之等价的机器语言程序的翻译过程。(不做指令优化)
4. 链接
可近似看成将目标文件信息合并······
- 链接的过程有:地址和空间分配,符号决议和重定位等步骤
- 链接解决的是⼀个项目中多⽂件、多模块之间互相调用的问题
重定位就是把程序的逻辑地址空间变换成内存中的实际物理地址空间的过程。
5. 运行环境
- 程序必须载入内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
- 程序的执行开始。接着调用main函数。
- 开始执行程序代码。这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址。(程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程⼀直保留他们的值)
- 终止程序。正常终止main函数或其他情况终止。