一、编译器作用
编译器本质上只是一个软件,这个软件读取一个文本文件(源码),对文本进行分析和处理,最终产生一个可以被计算机执行的二进制文件。
二、编译器的结构
据完成任务不同,可以将编译器的组成部分划分为前端(Front End)、优化器(Optimizer)与后端(Back End)。
- 前端主要指与源语言有关但与目标机无关的部分,包括词法分析、语法分析、语义分析与中间表示生成,将源代码转化为抽象语法树。
- 优化器则是在前端的基础上,对得到的中间代码进行优化,使代码更加高效。
- 后端主要指与目标机有关的部分,包括代码优化和目标代码生成等。
编译器为什么要分端?
“端”概念的提出对于编译技术的发展起到了至关重要的作用,它使编译器的框架更明晰,更利于集成与构造。
三、常见的编译器
1、GCC
(1)GCC简介
![]() |
GCC(GNU Compiler Collection,GNU编译器套件)是由GNU开发的编程语言译器。GNU编译器套件包括C、C++、 Objective-C、 Fortran、Java、Ada和Go语言前端,也包括了这些语言的库(如libstdc++,libgcj等。)。GCC 最初是作为 GNU 操作系统的编译器编写的,是一款开源软件。 |
---|---|
GCC是以GPL许可证所发行的自由软件,也是GNU计划的关键部分。GCC的初衷是为GNU操作系统专门编写一款编译器,现已被大多数类Unix操作系统(如Linux、BSD、MacOS X等)采纳为标准的编译器,甚至在微软的Windows上也可以使用GCC。GCC支持多种计算机体系结构芯片,如x86、ARM、MIPS等,并已被移植到其他多种硬件平台。
GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。
(2)GCC结构
与大多数可移植编译器一样,基于gcc的编译器的编译过程在概念上可以分为三个阶段:
- 前端接口
- 每种受支持的语言都有单独的
- 前端获取源代码,将源代码转换为语义上等价的、与语言无关的抽象语法树(AST)。
- 这个AST语法和语义是由GIMPLE语言定义的,这是GCC拥有的与语言无关的最高级别的中间表示。
- 中间接口
- 负责诸如构建控制流图和优化这样的事情
- AST用于优化编译,降低为非严格的RTL(扩展),并运行基于RTL的优化来优化编译。不严格的RTL被移交给更低级的传递。
- 后端接口
- 这些通道的第一个任务是将非严格的RTL表示转换为严格的RTL,
- 或者换句话说,从匹配define_insn定义而不考虑约束的RTL模式,到完全匹配complete =insn= definition 包括所有操作数约束的RTL模式(现在处理这个问题的一个步骤是重新加载,但这不是最优的)。严格RTL通过的其他工作包括调度、执行窥视孔优化和发出汇编输出。
无论是AST还是非严格的RTL表示都不是完全独立于目标的,但GIMPLE语言是,而且在非严格的RTL形式中,表示仍然不是真正的机器组装,因此,在非严格的RTL上工作的传递在某种程度上仍然可以被认为是与目标无关的(即使是像combine这样的传递也不必太担心目标机器)。在严格的RTL上工作的传递实际上是汇编优化器,它显然需要考虑关于目标体系结构的更多信息。