【编译、链接、装载一】预处理、编译、汇编、链接

【编译和链接一】预处理、编译、汇编、链接三、编译器()——cc 四、汇编器()——as 五、链接器()——ld 六、执行hello.out七、gcc能做的事:预处理、编译、汇编、链接八、其他知识点 2、cpp3、gcc、g++4、问:c语言预处理、编译、汇编、链接这四个过程 , 在linux分别由哪些实现方式5、问:c语言预处理生成的hello.i文件 , 除了使用gcc可以编译成hello.s文件 , 还有哪些方式可以编译成hello.s文件
简介
对于平常的应用程序开发 , 我们很少需要关注编译和链接过程 , 因为通常的开发环境都是流行的集成开发环境(IDE) , 比如 等 。这样的IDE一般都将编译和链接的过程一步完成 , 通常将这种编译和链接合并到一起的过程称为构建(Build) 。即使使用命令行来编译一个源代码文件 , 简单的一句“gcc hello.c”命令就包含了非常复杂的过程 。
IDE和编译器提供的默认配置、编译和链接参数对于大部分的应用程序开发而言已经足够使用了 。但是在这样的开发过程中 , 我们往往会被这些复杂的集成工具所提供的强大功能所迷惑 , 很多系统软件的运行机制与机理被掩盖 , 其程序的很多莫名其妙的错误让我们无所适从 , 面对程序运行时种种性能瓶颈我们束手无策 。我们看到的是这些问题的现象 , 但是却很难看清本质 , 所有这些问题的本质就是软件运行背后的机理及支撑软件运行的各种平台和工具 , 如果能够深入了解这些机制 , 那么解决这些问题就能够游刃有余 , 收放自如了 。
一、被隐藏了的过程
C语言的经典 , “Hello World”程序 。
使用c语言做例子吧 , 我使用cpp的预处理过 , 但是预处理的文件太长了 。
#include int main(){printf("Hello World\n");return 0;}
在Linux下 , 当我们使用GCC来编译Hello World程序时 , 只须使用最简单的命令(源代码文件名为hello.c):
$gcc hello.c$./a.out
Hello World事实上 , 上述过程可以分解为4个步骤 , 分别是预处理()、编译()、汇编()和链接() , 如图所示 。
二、预处理器()——cpp1、预处理指令
$cpp hello.c > hello.i
2、预处理过程
预处理过程主要处理那些源代码文件中的以“#”开始的预编译指令 。比如 “#”、“# ”等 , 主要处理规则如下:
经过预编译后的.i文件不包含任何宏定义 , 因为所有的宏已经被展开 , 并且包含的文件也已经被插入到.i文件中 。所以当我们无法判断宏定义是否正确或头文件包含是否正确时 , 可以查看预编译后的文件来确定问题 。
3、预处理生成的hello.i文件
三、编译器()——cc 1、编译指令
编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件 , 这个过程往往是我们所说的整个程序构建的核心部分 , 也是最复杂的部分之一 。我们将在下一节简单介绍编译的具体几个步骤 , 这涉及编译原理等一些内容 , 由于它不是本书介绍的核心内容 , 所以也仅仅是介绍而已 。
目前公司产品有用到这部分的内容 , 因为公司产品中有自己的语言 。但是产品底层的词法分析和语法分析等部分不是我负责的 。后面有机会的话继续深入的了解下 。