您的位置:首页 > 其它

Gcc编译过程分解

2018-03-17 23:24 190 查看
       我们都知道,”hello world“ 程序是程序员的启蒙语句,它的编译过程一气呵成,但是它的具体编译过程是什么呢?在编译果程中做了什么?
在Linux下,当我们使用GCC来编译“hello world”程序时,只需使用最简单的命令(假设源代码文件名为hello.c):
$ gcc hello.c ;  $ ./a.out ;
事实上,上述过程分为四个步骤,分别是预处理(Prepressing),编译(Compliation),汇编 (Assembly)和链接(Linking),如图所示



1.  预编译
        预编译过程主要处理那些以源代码文件中的以“ # ”开始的预编译指令,经过编译后的文件为 .i 文件。主要处理规则如下:
(1)处理所有的条件编译指令,比如 “ #if ”,“ #ifdef "  ,  " #ifndef "  , " #endif " , "  #else  " 等。
(2)处理”#include “  预编译指令,将包含的文件插入到该预编译指令的位置。
(3)将所有的”#define “所定义的宏进行宏替换。
(4)删除所有的注释 ”//“和”/* */“。
(5)添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息 及 用于编译时产生的编译错误或警告时能够显示行号。
(6)保留所有的 #pragma 编译器指令。
2.  编译
编译过程就是对预处理后的文件进行 词法分析,语法分析,语义分析 及 优化后产生相应的汇编代码文件。
相当于命令$ gcc -S hello.i -o hello.s
产生的文件为.s 文件。
(1)词法分析
       将源代码的字符序列分割成一系列的记号。词法分析所产生的记号一般分为如下几类:关键字,标识符,字面量和特殊符号,将所对应的符号放入符号表中。
(2)语法分析
       语法分析器将对产生的记号进行语法分析,从而产生语法树,即以表达式为结点的树。在语法分析阶段对一些内容进行区分,如果表达式不合法,编译器就会报出错误。
(3)语义分析
      对语法树的表达式标识类型 。
3. 汇编
      将汇编代码变成机器可以执行的指令,每一个汇编语句对应一条机器指令。它没有复杂的语法,也不需要做指令优化。
相当于命令$ gcc -c hello.s -o hello.o;
此时生成目标文件,即 .o 文件。
4. 链接
      链接的主要内容就是将各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。链接的过程包括了地址和空间分配,符号决议和重定位等。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: