07-目标代码生成

目标机器

  • 内存:堆、栈,都有地址

  • 寄存器:n个,4字节

指令

  • Load/Store

    • LD R0,a(R2): 从a+R2中取

    • LD R0,*R1:把R1的值作为地址去取

    • LD R1,*100(R2)100+R2位置的值作为地址去取

    • LD R0,#5R0=5

    • ST addr,R0

  • Calculation

    • OP dst,src1,src2

  • Jump

    • BR L/addr

    • Bcond R,L/addr

内存/地址

  • 每一条语句中的标签对应一个地址

  • 可使用objdump查看反汇编

## 查看反汇编代码
clang -c heello.c -o hello.o
objdump -D hello.o

内存分布

  • 代码区

  • 静态区/全局变量

  • 堆🔽

  • 空闲区域

  • 栈🔼

  • 代码/全局变量的地址由编译器决定

  • 堆/栈中变量的地址由代码决定

栈区

  • 栈帧:Frame

    • 本地变量

    • 返回值,参数

    • 返回地址

    • 需要保存和恢复的数据

  • 栈指针:SP,进出栈通过改变 SP 来实现

  • 函数调用前

    • 保存现场,将寄存器入栈:SUB SP,SP,#4 ST 4(SP),R0

    • 将返回地址和参数入栈:SUB SP,SP,#4 ST 4(SP),Label

    • 跳转到函数:BR Label

  • 函数调用中

    • 根据实际情况分配空间:SUB SP,SP,#4*nn为局部变量的个数+1(返回值)

  • 函数调用后

    • 保存返回值:LD R0,4(SP)

    • 栈帧出栈:ADD SP,SP,#4*n

    • 根据栈中的返回地址,返回到调用函数的地址:BR 4(SP)

    • 恢复数据,获取返回值

  • 当抛出异常时,可能会弹出多个栈帧

    • try:记录 catch 的位置

    • throw:跳转到 catch

堆区

  • malloc new

  • 关注效率,减少分割

  • 手工管理/gc

块内优化

基于语法树的指令选择

  • 定义规则通过模式匹配生成指令

模式
指令

叶节点a

LD R0,a

运算符节点 op x

op Rn,R1,R2 ST x,Rn

a = x - y
if x >= y goto L
  • 上面的代码能否被优化成if a >= 0 goto L

    • 不能:可能会溢出

其余优化

  • 定义规则进行匹配

  • Algebraic Identities:使用代数恒等式来简化表达式

    • x2=xxx^2 = x\cdot x

  • Machine Idioms:使用机器指令的特性来优化

  • Redundant Load/Store:消除冗余的加载和存储

Peephole 优化

  • 在小范围内优化代码

  • 定义规则进行匹配

最后更新于