编译器

什么是编译器

编译器是指从高级语言到低级语言的翻译器,同样的技术可用于区别种类语言之间的翻译。编译器是一种电脑程序,它会将用某种编程语言写成的源代码(原始语言),转换成另一种编程语言(目标语言)。

它紧要的目的是将便于人编写,阅读,维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序,也就是可执行文件。编译器将原始程序(Source program)作为输入,翻译产生使用目标语言(Target language)的等价程序。源代码一般为高阶语言 (High-level language), 如 Pascal、C、C++、C# 、Java 等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)。

一个现代编译器的紧要工作流程如下: 源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 汇编程序 (assembler) → 目标代码 (object code) → 链接器 (Linker) → 可执行文件 (executables)

编译器的分类

典型的编译器输出是由包含人口点的名字和地址以及外部调用的机器代码所组成的目标文件。一组目标文件,不必是同一编译器产生,但使用的编译器必须采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的可执行程序。

在运行历程中,编译器又可分成只依赖于源语言的编译器前端和只依赖于目标语言的编译器后端两大部分,编译器前后端结构如图所示。

前端紧要负责解析(parse)输入的源程序,由词法解析器和语法解析器协同工作。词法解析器负责把源程序中的“单词”(Token)找出来,语法解析器把这些分散的单词按预先定义好的语法组装成有意义的表达式、语句、函数等。例如“a=b+c”,前端词法解析器看到的是“'a'='b'+'c'”,语法解析器按定义的语法,先把它们组装成表达式“b+C”,再组装成“a=b+c”的语句。前端还负责语义(semantic checking)的检查,例如检测参与运算的变量是否是同一类型的,简单的错误处理。最终的结果常常是一个抽象的语法树AST(Abstract Syntax Tree),这样后端可以在此基础上进一步优化处理。编译器后端紧要负责解析、优化中间代码以及生成机器代码。一般来说所有的编译器解析、优化、变型都可以分成两大类:函数内实行和函数间实行。很明显,函数间的解析优化更准确,但需要更长的时间来完成。

一般编译器可以分为以下两类:

①“本地”编译器:编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码。

②交叉编译器:编译器也可以生成用来在其他平台上运行的目标代码,交叉编译器在生成新的硬件平台时非常有用。

交叉编译这个概念的出现和流行是和嵌入式系统的广泛进展同步的。在实行嵌入式系统的开发时,运行程序的目标平台通常只有有限的存储空间和运算能力。例如常见的ARM平台,其一般的静态存储空问为16~32MB,而处理器的主频为100~500MHz。这种状况下,在ARM平台上实行本机编译就不太可能了,这是因为一般的编译工具需要很大的存储空间,并需要很强的处理器运算能力。为了解决这个问题,交叉编译工具就应运而生了。通过交叉编译工具,就可以在CPU能力很强、存储控件足够的主机平台上(例如通用计算机)编译出针对其他运行平台的可执行程序。

在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,这个编译历程就叫交叉编译。也就是在主机平台上开发程序,并在这个平台上运行交叉编译器,编译出程序,这个编译程序将在目标平台上运行。这里需要注意的是所谓平台,实际上包含两个概念:体系结构和操作系统。同一个体系结构可以运行区别的操作系统;同样,同一个操作系统也可以在区别的体系结构上运行。举例来说,常说的X86Linux平台实际上是IntelX86体系结构和LinuxforX86操作系统的统称;而X86WinNT平台实际上是IntelX86体系结构和WindowsNTforX86操作系统的简称。

在交叉编译技术中有两种比较典型的实现,一个称之为Java模式,即Java的字节码编译技术;另一个称之为GNUGCC模式,即通常所讲的CrossGCC技术。Java模式(如图所示)的最大特点是引入了一个自定义的虚拟机,即Java虚拟机JVM(Java Virtual Machine)。所有Java源程序都会首先被编译成只在这个虚拟机上才能执行的“目标代码”:字节码(Bytecode)。在实时运行时,可以有两种运行方式:一种是编译所获得的字节码由JVM在实际计算机系统上执行;另一种方式是通过Java实时编译器(Just-In-TimeCompiler)将字节码首先转换成本地机可直接执行的目标代码,而后交给实际的计算机系统运行。这实际上是一个两次编译历程,一次是非实时的,一次是实时的。由于第一次是非实时编译,Java编译器生成的是基于JVM的“目标代码”,可以将它的编译技术也称为交叉编译。

GCC模式(如图所示)通过CrossGCC直接生成目标平台的目标代码,从而能够直接在目标平台上运行。这里的关键是CrossGCC的生成和选择问题。需要根据目标平台的区别,选择针对这个平台的CrossGCC。GCC模式和Java模式的最大区别在于GCC直接生成目标平台的目标代码,而Java模式首先只是生成字节码,只有在有JIT编译器的参与下才会进一步生成目标平台的目标代码。研究表明,Java模式虽然可以通过两个编译历程生成目标代码,但是因为两次编译的优化存在相互冲突,最终的目标代码的执行效率也不是很高。而GCC模式由于直接能够生成目标代码,其执行效率一般很高。

郑重声明:东方财富网发布此信息的目的在于传播更多信息,与本站立场无关。东方财富网不保证该信息(包含但不限于文字、数据及图表)全部或者部分内容的准确性、真实性、完整性、有效性、及时性、原创性等。相关信息并未经过本网站证实,不对您构成任何投资建议,据此操作,风险自担。

扫一扫下载APP

扫一扫下载APP
信息网络传播视听节目许可证:0908328号 经营证券期货业务许可证编号:913101046312860336 违法和不良信息举报:021-34289898 举报邮箱:jubao@eastmoney.com
沪ICP证:沪B2-20070217 网站备案号:沪ICP备05006054号-11 沪公网安备 31010402000120号 版权所有:东方财富网 意见与建议:4000300059/952500