当前位置:C++技术网 > 资讯 > 编译程序过程详解-编译器(cl.exe),汇编器,链接器,加载器1

编译程序过程详解-编译器(cl.exe),汇编器,链接器,加载器1

更新时间:2016-01-31 14:04:44浏览次数:1+次

编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。
源代码-->预处理-->编译-->优化-->汇编-->链接-->可执行文件
源程序经过编译器被编译为等价的汇编语言模块,在经过汇编器产生出于目标平台CPU已知的机器码模块(也就是目标(.obj)文件,由编译所生成的文件,以机器码的形式包含了编译单元里所有的代码和数据,此文件是以二进制的形式存在的)。尽管机器码模块中包含的指令已经可以被目标CPU所执行,但其中可能还包含没有解决的名称和地址引用,导出符号表等,因此需要链接器解决这些问题,并产生出符合目标平台上的操作系统所要求格式的可执行模块。当用户执行程序时,操作系统的加载器会解读连接器记录在可执行模块中的格式信息,将程序中的代码和数据“布置”在内存中,成为真正可以运行的内存映像。
一个由C/C++编译的程序的内存分布分为以下几个部分:
1、  栈(stack):也是我们所说的堆栈,是由编译器自动分配释放,用来存放函数参数值,函数的返回地址,非静态局部变量的值等。其操作方式类似于数据结构中的栈(后进先出LIFO)。
2、  堆(Heap):一般由程序员分配释放,若程序员不释放,程序结束可能由OS回收。
3、  全局区(静态区):全局变量和静态变量存储在这一块,初始化的全局变量河静态变量放在一块区域,未初始化的全局变量静态变量放在相邻的另一块区域(BSS)。程序结束后由系统释放。
4、  文字常量区:常量字符串放在这个区域。
5,程序代码区:存放函数体的二进制代码。
根据C++标准,一个编译单元(Translation Unit)是指一个.cpp文件以及这所include的所有.h文件,.h文件里面的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件,后者拥有PE(Portable Executable,即Windows可执行文件)文件格式,并且本身包含的就是二进制代码,但是不一定能执行,因为并不能保证其中一定有main函数。当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后,再由链接器进行链接成为一个.exe或.dll文件。
通常我们所说的程序经过编译器编译成目标文件,并不是指上述中的编译器(cl.exe)编译之后的文件哦,这是个误区。具体请看下面的过程:
Source--(编译器)--> Assembly--(汇编器)-->Obj--(链接)-->PE/ELF

编译器和汇编器做的主要的工作都是翻译工作,因此以目标代码(机器码)为界,可以吧程序的构建过程分为编译和链接两个阶段。
请参考《VS编译器底层设计粗讲-cl.exe,.obj,link.exe工作运行
编译器运行-预编译,编译,汇编,链接2
编译器运行-预编译,编译,汇编,链接1》这些文章可以作为你对编译器的一些零碎知识的了解资料