标签:
当我们编写一个程序并编译执行,如下(hello.c)
#include <stdio.h> int main() { printf("Hello World\n"); return 0; }
/*编译执行*/ $gcc hello.c -o hello.out $./hello.out Hello World
那么在其中执行了如图的过程:
其中的主要过程包括:
预处理(Propressing):处理"#define、#include、#if……"等,删除注释,添加行号,但保留所有#pragma编译器指令;
编译(Compilation):词法分析、语法分析、语义分析及优化后产生汇编代码文件;
汇编(Assembly):将汇编代码转换成机器可以执行的指令;
链接(Linking):将所有需要的静态、动态库、文件等链接成为可执行程序。
也就是上图中的编译部分,主要过程共分为6步,如下图:
扫描(Scanner):用类似于有限状态机,把代码分割成一系列记号(Token);
语法分析(Parser):通过对记号进行分析,生成语法树(Syntax Tree);
语义分析(Semantic Analyzer):完成表达式语法层面的分析,并不关心意义;如不会处理两个指针相乘;
源代码优化(Source Code Optimizer):将语法树转换成中间代码,如三地址码 x = y op z;
代码生成(Code generator): 初步生成目标代码;
目标代码优化(Code Optimizer):将目标代码优化为最终的代码。比如选择合适的寻址方式、使用位移来代替乘法运算、删除多余指令等。
标签:
原文地址:http://www.cnblogs.com/bugutian/p/5087577.html