自己动手构造编译系统:编译、汇编与链接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文件的结构和组织。

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

相关文章
|
1月前
|
存储 自然语言处理 编译器
编译和链接(翻译环境:预编译+编译+汇编+链接​、运行环境)
编译和链接(翻译环境:预编译+编译+汇编+链接​、运行环境)
|
3月前
|
存储 缓存 Linux
C语言编译过程——预处理、编译汇编和链接详解
C语言编译过程——预处理、编译汇编和链接详解
|
11月前
|
C语言
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(三)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(三)
|
11月前
|
编译器 C语言
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(二)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(二)
|
11月前
|
存储 Java C++
汇编语言、寄存器分类及程序计数器
汇编语言、寄存器分类及程序计数器
81 0
|
11月前
|
存储 自然语言处理 程序员
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(一)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(一)
|
存储 API C语言
从反汇编看恶意程序的C语言结构(二)
从反汇编看恶意程序的C语言结构
93 0
|
存储 程序员
Win知识 - 程序是怎样跑起来的——汇编语言的语法是“操作码+操作数”
Win知识 - 程序是怎样跑起来的——汇编语言的语法是“操作码+操作数”
90 0
Win知识 - 程序是怎样跑起来的——汇编语言的语法是“操作码+操作数”
|
编译器 C语言 C++
Win知识 - 程序是怎样跑起来的——通过编译器输出汇编语言的源代码
Win知识 - 程序是怎样跑起来的——通过编译器输出汇编语言的源代码
199 0
|
编译器 C语言
Win知识 - 程序是怎样跑起来的——汇编语言和本地代码是一一对应的
Win知识 - 程序是怎样跑起来的——汇编语言和本地代码是一一对应的
111 0
Win知识 - 程序是怎样跑起来的——汇编语言和本地代码是一一对应的