经过两天的采集,总结决定今天晚上将linux下c++编译器 gcc 编译原理进行一个简单的总结,一个是希望有的知识不单单是会用而且还能够清楚的将内容输出;
**环境和系统:**linux系统 编译器是gcc;
gcc简介: gcc(GNU编译器套件[GNU Compiler Collection]),包含C,C++,Objective-C,Fortran,Java,Ada,Go等语言的库;
相关概念: 写完代码后如果想要将代码运行都是离不开编译,那编译最主要的就是编辑器的作用了,正常情况下我们会遇到于编译器有关的用例举两个例子:
编译:从严格意义上讲编译就是将高级语言转化为低级语言,通常是指汇编语言甚至是机器代码,
交叉编译:如果代码在同一个平台上(相同的CPU或操作系统)上进行编译,生成代码可以在其他平台上进行执行,这就是交叉编译,
反编译: 是指将里面低级原因或者机器代码转化成高级语言的过程;
语言翻译: 是指将一种语言编写的程序转化成另一中等级和复杂的语言的过程;
语言重写: 将语言表达式转换成另一种形式,以更好的适应特定的任务的过程,比如优化;
编译流程: gcc编译 .cpp 文件一共包含四个内容: 预处理,编译,汇编,链接;
详细步骤:
在处理前有个前提就是以及在编辑器上写好了你的代码 生成了.cpp 和 .h 的文件
1.预处理:
预编译过程主要处理哪些源代码中以#号开始编译的与编译指令,
将#include 关键字标示的含义有定义的文件(包含文件或者头文件)包含到源代码文件中;
将 #define 语句指定的值转化成常量;
在 代码中调用宏的位置将宏定义转化成代码;
根据 #if #elif #endif 指令的位置包含或者派出特定部分代码;
预处理程序输出的内容就是转换完成的C/C++代码,这些输出的结果会供下一个编译阶段使用,到这部就会生成一个.ii 的文件,但是如果是c代码就会生成一个 .i 的文件;
2.编译:
在编译阶段主要的作用就检查你的语法语义,但是在这之前编译器会先将代码转化成便于处理的形式,主要就是将里面不必要的空格和注释先删掉,然后才是检查你的语法语句,编译器会在检查到不满足语法规则的时候进行报错或者进行警告,就是我们最怕看到的ERROR和
Warning;具体语法分析逻辑如下:
词法分析:将原代码分割成不可分割的单词;
语法分析:将上一步提取出来的单词连接成单词序列,然后根据语言规则验证它是否合理;
语义分析: 检测上面通过的语法规则又没有实际意义,比如将数赋值给对象,在语法中不会报错但在这里就可能无法通过(除非对象重载了赋值操作符);
3.汇编阶段:
通过上一层之后,在这一层编译器会将标准的语言集合转化成特定的CPU指令集语言集合;
4.链接:
通过连接器对程序内存映射提供各种各样的节,并将独立的节组合成最终的程序内存映射节,其中就包括内存的映射和依赖库的映射;
cmd手动汇编:
背景介绍: 已在本地路径编写test.cpp文件,目的是为了编译成可执行程序test.exe;
流程如下:
预处理(进行宏替换)
gcc -E test.c -o test.ii (只预处理生成一个test.ii文件)
1.预处理功能主要包括:宏替换,展开头文件,条件编译,去注释等。
2.预处理指令是以#开头的代码行。
3.-E:让gcc在与处理结束后停止编译过程。
4.-o:指目标文件test.ii已经过预处理的C原始程序。
编译(生成汇编)
gcc -S test.ii -o test.s (只走到编译阶段生成test.s文件)
1.在这个阶段中,gcc首先要检查代码的规范性,是否有语法错误等。以确定代码要做的功工作,在检查无误后,gcc把代码翻译成汇编语言。
-S:只进行编译,不进行汇编,生成汇编代码。
汇编 (生成机器可识别代码)
gcc -c test.s -o test.o (test.o计算机已经可以识别但还不可以执行)
把编译阶段生成的.s文件转换为目标文件。
-c:看到汇编代码以转化为.o的二进制目标代码
链接(生成可执行文件或库文件)
gcc test.o -o test.exe 生成最终的exe可执行程序
以上就是全部内容如果不足之处欢迎批评指正;
E-mail : [email protected];