代码生成

  • 1. 代码生成的相关问题
  • 2. 简单的计算机模型
  • 3. 简单的代码生成器
  • 3.1 基本块、流图与循环
  • 3.2 下次引用信息与活跃信息
  • 3.3 简单的代码生成


代码生成是编译器的最后一个阶段,它以中间代码符号表信息为输入,生成最终可以在机器上运行的目标代码。

1. 代码生成的相关问题

  1. 中间代码形式
    中间代码有多种形式,其中树与后缀式形式适用于解释器,而对于希望生成目标代码的编译器而言,中间代码多采用与一般机器指令格式相近的三地址码形式。
  2. 目标代码形式
    目标代码的形式可以分为两大类:汇编语言和机器指令。机器指令又可以根据需求的不同分为绝对机器代码和可再定位机器代码。绝对机器代码的优点是可以立即执行,一般应用于一类称为load-and-go形式的编译模式,即编译完成后立即执行,不形成磁盘形式的目标文件,这种形式特别适合于初学者。可再定位机器代码的优点是目标代码可以被任意链接并装入内存的任意位置,是编译器最多采用的代码形式。
    汇编语言作为一种中间输出形式,便于软件开发人员的测试:load-and-go提供给初学者使用;可再定位机器代码用于真正的软件开发。出于教学的目的,此处选择汇编语言作为目标代码。
  3. 寄存器的分配
    由于寄存器的存取速度远远快于内存,因而一般情况下总是希望尽可能多地使用寄存器,但寄存器的个数是有限的,因此,如何分配寄存器,是目标代码生成时需要考虑的重要因素之一。
  4. 计算次序的选择
    代码执行的次序不同,会使代码的运行效率有很大差别。在生成正确目标代码的前提下,优化安排计算次序和适当选择代码序列,也是代码生成需要考虑的重要因素之一。

2. 简单的计算机模型

  1. 指令系统与寻址方式
  2. 编译原理实验中间代码生成python 编译原理 代码生成_编译原理实验中间代码生成python

  3. 特殊指令
  4. 编译原理实验中间代码生成python 编译原理 代码生成_编译原理实验中间代码生成python_02

  5. 指令的代价
  6. 编译原理实验中间代码生成python 编译原理 代码生成_代码生成_03

3. 简单的代码生成器

3.1 基本块、流图与循环

  • 基本块:一段顺序执行的语句序列
  • 开始语句:第一条语句,简称开始
  • 结束语句:最后一条语句,简称结束
  • 构造流图:将基本块作为一个图中的节点,节点之间的边指示程序控制流的转移,就可以形成一个程序的图形表示,称为控制流图或简称为流图。
  • 循环:我们称流图中具有下述性质的节点集合L是一个循环(loop):

3.2 下次引用信息与活跃信息

编译原理实验中间代码生成python 编译原理 代码生成_编译原理_04

3.3 简单的代码生成

  1. 寄存器的分配原则
    在指令的执行代价中,寄存器的代价最小,因此总是希望将尽可能多的运算对象放在寄存器中。由于任何一个计算机模型中的寄存器个数都是有限的,所以需要根据一些原则对寄存器进行分配。下述是基于基本块的寄存器分配的一般原则:
  • 当生成某变量的目标代码时,让变量的值或计算结果尽量保留在寄存器中,直到寄存器不够分配时为止,这样可以减少对内存的存取次数,降低代价。
  • 当到基本块结束语句时,将变量的值存放在内存中。因为一个基本块可能有多个后继节点,同一个变量名在不同前驱节点的基本块内结束语句前存放的R可能不同,或没有定值,所以应该在结束语句前把寄存器的内容放在内存中,从而使得每个变量进基本块时,值均在内存中。
  • 对于在一个基本块内、后边不再被引用的变量所占用的寄存器应尽早释放,以提高寄存器的利用效率。