中间表示- 三地址码

使用三地址码的编译器结构

三地址码的基本思想

(1)给每个中间变量和计算结果命名,没有复合表达式

(2)只有最基本的控制流,没有各种控制结构(if、do、while、for等等),只有goto,call等

(3)所以三地址码可以看成是抽象的指令集,如通用的RISC

 我们来看一个例子

a = 3 + 4 * 5;

if (x < y)
    z = 6;
else
    z = 7;

把上述程序翻译为三地址码后,程序如下:

x_1 = 4;
x_2 = 5;
x_3 = x_1 * x_2;
x_4 = 3;
x_5 = x_4 + x_3;
a = x_5;

Cjmp (x < y, L_1, L_2);  // 条件跳转
L_1:
    z = 6 ;
    jmp L_3;
L_2:
    z = 7;
    jmp L_3;
L_3:
    ...

三地址码的定义

如何定义三地址码数据结构?

enum instr_kind {INSTR_CONST, INSTR_MOVE, ...};
struct Instr_t
{
    enum instr_kind kind;
};

struct Instr_Add
{
    enum instr_kind kind;
    char *x;
    char *y;
    char *z;
};

struct Instr_Move
{
    /* data */
};

如何生成三地址码?

以 C--生成三地址码 为例

要写如下几个递归函数来生成三地址码

Gen_P(P);Gen_F (F) ;Gen_T(T);Gen_S(S); Gen_E(E);

我们重点关注语句的代码生成,其余的可参考代码生成- 寄存器计算机_青衫客36的博客-CSDN博客

 

Gen_S(S s)
{
    switch (s)
    {
        case x = e:
            x1 = Gen_E(e);  // 每个表达式的值要放在一个变量里
            emit("x = x1");
            break;

        case printi(e):
            x = Gen_E(e);
            emit("printi(x)");
            break;
        
        case printb(e):
            x = Gen_E(e);
            emit("printb(x)");
            break;

        case x(e1, ..., en):
            x1 = Gen_E(e1);
            ...;
            xn = Gen_E(en);
            emit("x(x1, ..., xn)");
            break;

        case return e:
            x = Gen_E(e);
            emit("return x");
            break;

        case if (e, s1, s2):
            x = Gen_E(e);
            emit("Cjmp(x, L1, L2)");
            emit("Label L1:");
            Gen_SList(s1);
            emit("jmp L3");
            emit("Label L2:");
            Gen_SList(s2);
            emit("jmp L3");
            emit("Label L3:");
            break;

        case while (e, s):
            emit("Label L1:");
            x = Gen_E(e);
            emit("Cjmp(x, L2, L3)");
            emit("Label L2:");
            Gen_SList(s);
            emit("jmp L1");
            emit("Label L3:");
            break;

        default:
            break;
    }
}

小结

(1)三地址码的优点:

  • 所有的操作都是原子的,变量!没有复合结构
  • 控制流结构被简化了,只有跳转
  • 是抽象的机器代码,向后做代码生成更容易

(2)三地址码的不足:

  • 程序的控制流信息是隐式的
  • 可以做进一步的控制流分析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫客36

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值