简介
嵌入式编译程序是指应用在嵌入式系统中的编译程序。
在 计算机上执行一个高级语言程序需要两步:利用编译器将高级语言程序翻译成为机器语言程序; 运行得到的 机器语言程序求得计算结果。 编译器是将高级语言在逻辑等价的原则上翻译为底层的汇编语言或者 机器语 言的计 算机程 序。在 这里,输入 的高级语言称 作源程序(Source Language) , 而输出的底层语言称作目标语 言 (TargetLanguage)。编译程序在计算机系统中的作用如下图所示:1
嵌入式系统嵌 入式系统是基于特定用途的 , 以计算机技术为基础 ,其软硬件具备良好可裁剪性的专用计算机系统,适用于对功能、可靠性、成本、体积、 功耗有严格要 求的场合。它一般由嵌入式微处理器、 外围硬件设备、嵌入式操作系统以及用户应用程序四个部分组成。从 20 世纪 60年代中期集成电路诞生至今,嵌入式系统应用已经有接近 40 年的发展历史。
通常来说,嵌入式系统具备以下特点:
(1)体积小,重量轻。
(2)结构简单、功耗低、可靠性高。
(3)便于规模化生产、价格相对低廉。
(4)模块化、芯片化。
(5)强调量身定做的原则。
由于具备上述特点,嵌入式系统被广泛应用于制造业、过程控制、通信、仪器仪表、汽车 、船舶、航空航天、武器系统、个人电子消费品等领域 。伴随着集成电路制造工艺的发展, 尤其是单片机 处理器技术的不断 进步 ,使嵌入式系统的应用进入到了突飞猛进的发展阶段。如美国休斯公司 1995 年研制成功的应用于航空航天高速图像处理的新型三维嵌入式计算机系统。
发展很长一段时间以来, 嵌入式系统的 软件都 采用汇编语言直接编写,这就使得嵌入式系统的开发只能由汇 编语言 程序员采用原始的开发工具完成。由此而造成的直接后果就是 使嵌入式系统软件 开发的效率低下、周期过长;而且利用汇编语言开发的程 序代码可读 性、可移植性 、可维护性、可重用性 都相对 较差, 从而使 开发出的应 用软件无法具有很好的可靠性。
随着嵌入式系统硬件性能的不断提高,嵌入式系统的应用场合在不断扩展、性能要求在不断增加,在嵌入式系统上运行的软件也越来越庞大、结构更加复 杂。因 此过去对于嵌入式系统软件在时 、空间方面的限制现在已经不是设计时所考虑的最主要因素;相反,对嵌入式系统软件的可靠性、可维护性、可重入性则提出了更高的要求。
国外使用高级语言进行嵌入式系统开发的时间较早,例如 1975 年美国国防部为更好的进行航空航天嵌入式系统实 时控制而开发的高级程序 设计语言Ada。实践证明,使用高级语言进行嵌入式系统开发可以极大地提高程序的可维护性、可靠性、可重用 性和开发效 率。目前,嵌入式系统的开发平台已经向高级语言化和集成化方向发展,并多采用了交叉开发的方法。
编译器前端设计词法分析编译程序是在单词级别上对源程序进行分析和翻译,词法分析是编译程序的第一个阶段。在这个阶段,词法分析模块从源程序的起始位置开始按照顺序逐个读入字符并进行词法分析,并得出分析之后所产生的单词序列。词法分析程序的功能是输入源程序,输出单词符号。单词符号是一个程序设计语言的基本要素,根据 ANSI C 标准的基本规定和目标系统的功能需求,我们将单词符号划分为以下五种类型:
(1)关键字(或者称作保留字)。由 M68HC11 C 语言定义并具有固定意义的标识符号,例if、do、while、for等等。
(2)标识符。用于表示各种名字,例如变量名、数组名、过程名等。
(3)各种类型的常量。例如布尔常量、八位字符型常量、十六位整型常量。
(4)运算符。例如+、-、%、!等。
(5)界符。例如分号、逗号、括号等。
语法分析语法分析是编译过程中的核心部分。源程序在经过词法分析之后,其形式 由字符 流转化 成为单 词流。 语法分析就 是在输入程序 单词流的基础之上来分析并判定输入程序的语法结构是否符合语法规则。下图说明了语 法 分析 在编译过 程中的 作用以及词 法分析与语法 分析之间的相互关系。
符号表设计在编译过程中特别是在语义分析和代码生成过程中,编译程序需不断汇集和反复查证出现在源程序中各种名 字的属性和特征信息,这些信息通常被记录在符号表中。符号表的组织是编译过程中的一门重要技术,一个具有良好组织结构的符号表必须同时满足以下要求: 2
(1)正确的记录源程序中的各种名字属性以及特征信息。
(2)满足编译处理过程中对各种名字的不断汇集和反复查找。
在编译器对源程序的词法分析阶段,每当识别出一个新的符号名字(标识符),编译器都需要在符号表中查找该符号是否已经存在。如果不存在,则将该符号写入到符号表 中 。每一个符号的 相关信息将在后续的 语 法分析 、语义 分析过程中陆续填入符号表。符号表中的信息在编译的不同阶段都要用到。例如在语法和语义分析过 程中,符号表的记录信息将用于语义检查和中间代码生成,在目标代码生成过程中,符号表的信息将作为地址分配的依据。
符号表的组织是编译过程中的一门重要技术,一个具有良好组织结构的符号表必须同时满足以下要求:
(1)正确的记录源程序中的各种名字属性以及特征信息。
(2)满足编译处理过程中对各种名字的不断汇集和反复查找。
语义分析及中间代码生成在编译过程中语义分析主要实现两方面的功能:
(1)验证具有正确语法结构的源程序是否具有真正意义(静态语义分析)。
(2)对通过静态语义分析的源程序进行翻译(中间代码生成)。
中间代码优化对程序进行各种等价变换,使得从变换之后的程序出发能够生成效率更高的目标代码,称之为优化。优化可以在编译的各个阶段进行,但最主要的一类优化是在目 标代码生成之前, 针对语义分析所产生的中间代码进行的,这是因为对中间代码的优化不依赖于具体的计算机。优化的目的是为了产生执行效率更高的代码, 编译程序对中间代码的优化必须遵循一定的原则:
(1)等价原则。优化不应改变程序的运行结果。
(2)有效原则。优化产生的代码应具有更高的运行效率和更少的存储空间。
(3)成本原则。尽可能以较低的代价获得较好的优化效果。
目标代码生成目标代码生成部分是编译过程的最后一个阶段,它以编译前端产的信息作为输入, 输出与 具体目标机相关的 目标代码。编 译前端产生的信息包括优化之后的中间代码以及符号表中的相关信息 ,编译后端生成的目标代码可以是机器指令代码,也可以是汇编指令程序 。3
根据最终用途的不同,由目标代码生成器输出的目标代码由三部分组成:包含全局和静态数据的数据链区(对 应可执行文件中的数据段),包含目标指令和操作数的指令代码区(对应可执行文件中的代码段),包含数据和符号地址信息的地址区。
在代码生成过程中,编译程序需要不断的查询符号表以获取各种符号名字的信息,同时建立新的数据结构以存放输出的目标代码。
编译程序生成的目标指令最终需要装入目标机的寄存器执行, 因此如何为指令分配目标机的寄存器是代码生成时需要考虑的一个重要问题。对寄存器的分配需要遵循一些基本原则,例如当生成一条目标指令时,如果该指令的操作数已经存在于寄存器中,那么就可以直接对寄存器进行操作而无需将操作数重新装入。