翻译环境和运行环境
在任何ANSI C的实现中,都包含两种环境:翻译环境和运行环境。
翻译环境是将源代码通过C语言的编译器(VS的cl.exe)编译为目标文件,目标文件和链接库再通过C语言的链接器(VS的link.exe)链接成可执行程序,然后在运行环境中执行代码。
编译
编译又可以细分为预编译、编译和汇编。
预编译
预编译又称为预处理。在这一步.c源文件会经过以下处理成为.i文件。
• 将所有的 #define 删除,并展开所有的宏定义。
• 处理所有条件编译指令,如:#if……
• 处理#include包含的头文件,将头文件包含到里面去。
• 删除所有注释。
• 添加行号和文件标识,方便后续文件编译器生成调试信息。
• 保留所有#progma指令,后续编译器会使用。
也就是当我们写代码时,如果不确定写的宏定义和包含的头文件是否正确,可以通过.i文件来检查。
编译
编译就是将.i文件经过词法分析、语法分析、语义分析及优化生成相应的汇编代码.s文件。
• 词法分析会对源代码进行简单的扫描,提取出其中的关键字、标识符、字面量、特殊字符等。
• 语法分析,就是将上述记号生成一颗以表达式为节点的语法树。
• 语义分析就是通过语义分析器查看语法树的类型声明和转换,这个阶段会报出错误的语法信息
• 在编译阶段会汇总源代码所有的变量符号
汇编
汇编是将.s的汇编代码文件转化为机器语言的.obj(.o)目标文件。这个阶段还会生成相应的符号表。只是根据机器语言和汇编语言对照表翻译,一般不做优化。
链接
链接是将多个.obj文件和链接库链接在一起形成可执行程序。这个过程包括地址和空间分配,符号决议和重定位等这些步骤。也就是说链接解决的是一个项目中多文件、多模块之间互相调用的问题。
运行环境
可执行程序运行需要经过以下步骤:
•将代码载入内存,这个过程一般由操作系统完成。在某些独立环境中,如单片机,就需要人工手动完成。
•程序从main开始执行。
•形成各种运行时堆栈来存放局部变量,用静态内存存储静态变量。
•终止程序:正常终止main程序或者是意外终止。