自己动手构造编译系统:编译、汇编与链接1.4 设计自己的编译系统-阿里云开发者社区

开发者社区> 华章出版社> 正文
登录阅读全文

自己动手构造编译系统:编译、汇编与链接1.4 设计自己的编译系统

简介:

1.4  设计自己的编译系统

  

    根据以上描述,我们意欲构造一个能将高级语言转化为可执行文件的编译系统。高级语言语法由我们自己定义,它可以是C语言语法,也可以是它的一个子集,但是无论如何,该高级语言由我们根据编程需要自行设计。另外,我们要求生成的可执行文件能正常执行,无论它是Linux系统的ELF可执行文件,还是Windows系统的PE文件,而本书选择生成Linux系统的ELF可执行文件。正如本章开始所描述的,我们要做的就是:自己动手完成当初单击“编译”按钮时计算机在背后做的事情。

  然而在真正开工之前,我们需要承认一个事实——我们是无法实现一个像GCC那样完善的工业化编译器的。因此必须降低编译系统实现的复杂度,确保实际的工作在可控的范围内。本书对编译系统的实现做了如下修改和限制:

  1)预编译的处理。如前所述,预编译作为编译前期的工作,其主要的内容在于宏命令的展开和文本替换。本质上,预编译器也需要识别源代码语义,它与编译器实现的内容十分相似。通过后面章节对编译器实现原理的介绍,我们也能学会如何构造一个简单的预编译器。因此,在高级语言的文法设计中,本书未提供与预编译处理相关的语法,而是直接对源代码进行编译,这样使得我们的精力更关注于编译器的实现细节上。

  2)一遍编译的方式。编译器的设计中可以对编译器的每个模块独立设计,比如词法分析器、语法分析器、中间代码优化器等。这样做可能需要对源代码进行多遍的扫描,虽然编译效率相对较低,但是获得的源码语义信息更完善。我们设计的编译系统目标非常直接——保证编译系统输出正确的可执行文件即可,因此采用一遍编译的方式会更高效。

  3)高级语言语法。为了方便大多数读者对文法分析的理解,我们参考C语言的语法格式设计自己的高级语言。不完全实现C语言的所有语法,不仅可以减少重复的工作量,还能将精力重点放在编译算法的实现上,而不是复杂的语言语法上。因此在C语言的基础上,我们删除了浮点类型和struct类型,并将数组和指针的维数简化到一维。

  4)编译优化算法。编译器内引入了编译优化相关的内容,考虑到编译优化算法的多样性,我们挑选了若干经典的编译优化算法作为优化器的实现。通过对数据流问题优化算法的实现,可以帮助理解优化器的工作原理,对以后深入学习编译优化算法具有引导意义。

  5)汇编语言的处理。本书的编译器产生的汇编指令属于Intel x86处理器指令集的子集,虽然这间接降低了汇编器实现的复杂度,但是不会影响汇编器关键流程的实现。另外,编译器在产生汇编代码之前已经分析了源程序的正确性,生成的汇编代码都是合法的汇编指令,因此在汇编器的实现过程中不需要考虑汇编语言的词法、语法和语义错误的情况。

  6)静态链接方式。本书的编译系统实现的链接器采用静态链接的方式。这是因为动态链接器的实现相对复杂,而且其与静态链接器处理的核心问题基本相同。读者在理解了静态链接器的构造的基础上,通过进一步的学习也可以实现一个动态链接器。

  7)ELF文件信息。除了ELF文件必需的段和数据,我们把代码全部存放在“.text”段,数据存储在“.data”段。按照这样的文件结构组织方式,不仅能保证二进制代码正常执行,也有助于我们更好地理解ELF文件的结构和组织。

  综上所述,我们所做的限制并没有删除编译系统关键的流程。按照这样的设计,是可以允许一个人独立完成一个较为完善的编译系统的。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接