预处理器,编译器,汇编器,连接器
来源:互联网 发布:flash10.0软件下载 编辑:程序博客网 时间:2024/06/06 03:32
http://www.cnblogs.com/hutao886/p/5614296.html
http://www.cnblogs.com/chenwu128/archive/2012/06/01/2531425.html
1.2程序被其它程序翻译成不同的格式
hello程序的生命周期是从一个源程序(hello.c)(称为高级c语言)开始,被其它程序转化为一系列的低级机器语言指令,这些指令按照一种称为可执行目标程序的格式打包好,以二进制磁盘文件的形式保存。
例:unix> gcc -o hello hello.c可以实现源文件向目标文件的转化,该过程由编译程序完成。
hello.c ---->hello.i ---->hello.s ---->hello.o -->hello
(1).预处理(cpp):预处理器不止一种,而C/C++的预处理器就是其中最低端的一种——词法预处理器,主要是进行文本替换、宏展开、删除注释这类简单工作。
- gcc -E 选项可以得到预处理后的结果,扩展名为.i;
- C/C++预处理不做任何语法检查,不仅是因为它不具备语法检查功能,也因为预处理命令不属于C/C++语句(这也是定义宏时不要加分号的原因),语法检查是编译器要做的事情;
- 预处理之后,得到的仅仅是真正的源代码;
- GCC确实很强大,如果是用VC这种IDE,恐怕就不能看到预处理后的结果。
(2).编译器(ccl):将文本文件.i翻译成文本文件.s,得到汇编语言程序(把高级语言翻译为机器语言),该种语言程序中的每条语句都以一种标准的文本格式确切的描述了一条低级机器语言指令。
- gcc -S 选项可以得到编译后的汇编代码,扩展名为.s;
- 汇编语言为不同高级语言的不同编译器提供了通用的输出语言,比如,C编译器和Fortran编译器产生的输出文件用的都是一样的汇编语言。
(3).汇编(as):将.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件.o中(把汇编语言翻译成机器语言的过程)。
- gcc -c 选项可以得到汇编后的结果,扩展名为.o;
- .o是一个二进制文件,它的字节编码是机器语言指令而不是字符。如果在文本编辑器中打开.o文件,看到的将是一堆乱码。
- 把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析;语法分析;语义检查和中间代码生成;代码优化;目标代码生成。主要是进行词法分析和语法分析,又称为源程序分析,分析过程中发现有语法错误,给出提示信息。
(4).链接(ld):gcc会到系统默认的搜索路径”/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去。 函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。
从会敲代码开始,我们就知道编译器的重要性,没有这东西,我们的代码就是一堆字符而已。而编译器编译程序的步骤
主要有四个——预处理、编译、汇编和链接,最后得到可执行的目标文件。
四个步骤各自的工作会是怎么样的呢?不知为何,对这个东西有了点兴趣。以GCC为例,主要工作是这样的:
预处理阶段会调用cpp,
编译阶段会调用cc得到汇编程序,
汇编阶段调用as得到目标代码,
链接时调用链接程序ld 得到可执行文件。
由于四个步骤(其实本质上就是四个可执行代码)早就被编译器打包,一并替我们打理了,我们的工作是轻松了,
对于这几个过程究竟是怎样进行的,恐怕还是有个问号在脑中打转。
后面3个阶段的具体工作机制,我没有深入了解过,但还是可以说说预处理的。
在探究预处理的操作机制之前,了解预处理器是个什么东西还是很有必要的。
预处理器不止一种,而C/C++的预处理器就是其中最低端的一种——词法预处理器。
这种预处理器做的主要是进行文本替换、宏展开、删除注释这类简单工作。
再具体一点就是,预处理器cpp就是负责展开源文件中的宏,并把”#include ”的内容插入这类的工作。
空口无凭,直接上代码。其实也不算空口,毕竟也谷歌、维基过了。
源代码prepro.c 如下:
使用-E参数, 让GCC在预处理之后停止编译过程。执行:
那么,这时预处理后的结果是怎样的呢?贴图如下:
有图有真相,我们可以看到:
预处理器用stdio.h的内容替代了#include <stdio.h>
这一行;而宏PI也被替换为3.1415926;而且注释也被删除了。
总结:
★ C/C++预处理器什么都不会做,只是做宏替换和文本替换。
★ C/C++预处理是不会做任何语法检查的,不仅是因为它不具备语法检查功能,也因为预处理命令
不属于C/C++语句(这也是定义宏时不要加分号的原因),语法检查是编译器要做的事情。
★ 通过预处理之后,我们得到的是也仅仅是真正的源代码。
★ 还有就是,GCC这个东西确实很强大。如果是用VC这种IDE,恐怕就不能看到,预处理原来是这么个好玩的东西了。
- 预处理器,编译器,汇编器,连接器
- 预处理器、编译器、汇编、链接
- 预处理器-编译器-汇编器-链接器(转)
- 预处理器,编译器,汇编器和链接器
- 预处理器,编译器,汇编器和链接器
- 编辑器,编译器,语言,库,连接器,汇编器......你搞清楚了吗?
- 编辑器,编译器,语言,库,连接器,汇编器......你搞清楚了吗?
- 编译器和预处理器
- 编译器,汇编器原理
- 编译器比预处理器更有效!
- 输出编译器预处理器的中间文件
- gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接
- Effective C++(1-2) 编译器替换预处理器
- scheme编译器-预处理器(二)多态性的宏
- 编译器和解释器,预编译和预处理
- effective C++读书笔记 条款二 以编译器替换预处理器
- effective c++ item2总结:以编译器替换预处理器
- 编译器预处理
- 应用开发者必须了解的Kubernetes网络二三事
- JS获取浏览器或者系统宽高
- 通过form定义参数传值
- Android 版本与 Bluetooth 版本之间的关系
- CentOS Docker 安装
- 预处理器,编译器,汇编器,连接器
- vmware磁盘动态扩容
- 1.安装jdk
- 选择数据源(SQL Server 导入和导出向导)
- C++字符串输入
- CF870D Something with XOR Queries(异或+暴力枚举)
- 安心360CTO:谈自建手机定位数据库的必要性
- 【Java学习4.2.1】if条件语句
- C 常量