本文概述
在代码生成阶段, 可能会出现各种问题:
- 输入到代码生成器
- 目标程序
- 内存管理
- 指令选择
- 寄存器分配
- 评估顺序
1.输入到代码生成器
- 代码生成器的输入包含源程序的中间表示和符号表的信息。源程序由前端生成。
- 中间表示有几种选择:a)后缀表示法b)语法树c)三个地址代码
- 我们假设前端产生低级的中间表示, 即其中的名称值可以由机器指令直接操作。
- 代码生成阶段需要完整的无错误的中间代码, 如输入所要求的。
2.目标程序
目标程序是代码生成器的输出。输出可以是:
a)汇编语言:它允许子程序被单独编译。
b)可重定位的机器语言:它使代码生成过程更容易。
c)绝对机器语言:可以将其放置在内存中的固定位置, 并可以立即执行。
3.内存管理
- 在代码生成过程中, 符号表条目必须映射到实际的p地址, 而级别则必须映射到指令地址。
- 源程序中的名称到数据地址的映射是由前端和代码生成器共同完成的。
- 局部变量是激活记录中的堆栈分配, 而全局变量处于静态区域。
4.指令选择
- 目标机器指令集的性质应完整且统一。
- 当你考虑目标机器的效率时, 指令速度和机器习惯用法是重要的因素。
- 生成代码的质量可以通过其速度和大小来确定。
例:
这三个地址代码是:
a:= b + c
d:= a + e
低效的汇编代码是:
MOV b, R0 R0→b
ADD c, R0 R0 c + R0
MOV R0, a a → R0
MOV a, R0 R0→ a
ADD e, R0 R0 → e + R0
MOV R0, d d → R0
5.寄存器分配
寄存器的访问速度比内存访问速度快。寄存器中涉及操作数的指令比存储器操作数涉及的指令更短, 更快。
使用寄存器时, 出现以下子问题:
寄存器分配:在寄存器分配中, 我们选择将驻留在寄存器中的变量集。
寄存器分配:在寄存器分配中, 我们选择包含变量的寄存器。
某些机器需要某些操作数和结果的偶数对寄存器。
例如:
考虑以下形式的除法指令:
D x, y
哪里,
x是偶数/奇数寄存器对中的股息偶数寄存器
y是除数
偶数寄存器用于保存提醒。
旧寄存器用于保存商。
6.评估顺序
目标代码的效率可能会受到执行计算顺序的影响。某些计算顺序比其他计算顺序需要更少的寄存器来保存中间结果。
评论前必须登录!
注册