网站不足重庆seo
three–address code:x = y op z
Quadruple:三地址码表现形式:(op, y, z, x)
- 注意顺序不能改变,操作总是第一个,目标总是最后一个,没有的则空出来。
- 如果是<=则转为>,>是gt
Triple:
- 针对四个全满的,将目的变量省去,需要计算结果则填写算式的地址,如果没有全满则不需要省
- Label直接替换为该条代码的地址
比如赋值:fact = 1,Triple: (asn, 1, fact),此时不需要省略
比如乘法:x = y mul z Triple: (mul, y, z),此时需要省略,用到x的地方替换为这条的地址
操作 | 三地址码 | 四元组 | 3元组 |
---|---|---|---|
fact = 1 | fact = 1 | (asn, 1, fact, _) | (asn, 1, fact) |
if(x>=0) | t1 = x > 0 if_false t1 goto L1 | (gt, x, 0, t1) (if_false, t1, L1, _) | (gt, x, 0) (if_false, (1), (11)) |
Lable L2 | Lable L2 | (Lab, L2, _, _) | 无 |
三地址码取值和赋值都是相同的
x.i:
t1 = &x + field_offset(x,i)
t2 = *t1 取地址进行操作
*t1 = 3 赋值
p->lchild=p,求地址进行操作。p本身就是一个地址
t1 = p + filed_offset(*p,lchild)
*t1 = p
a[j+2]
t1 = j + 2
t2 = a[t1]
a[t1] = t2
if 语句 if(E) S1 else S2
t1 = E
if_f t1 goto L1
S1
goto L2
L1: S2
L2:
while语句 while(E) S
L1: t1 = E
if_f t1 goto L2
S
goto L1
L2:
f(int x, iny){return x+y}:
形参直接使用,开始时用entry声明
entry f
t1 = x+y
return t1
调用时用arg传参,用call调用
begin_args
t1 = 3 + 4
arg t1
arg 3
call f
如果该条语句是简单语句,则直接生成,如果语句复杂,则
给定代码生成P-code|三地址码|三元组:
- 先画出parse tree
- 用后序遍历这棵树,
- 如果三地址码,则每个非根节点都取名一个临时变量
- 对于a[x+y], a作为左节点,[]作为根,x+y作为右子树
情况 | p-code |
---|---|
操作数为常数2 | ldc 2 |
操作数为变量a | lod a |
操作数为a的地址z,或者a被赋值 | lda a |
加法 | adi |
减法 | subi |
乘法 | mpi |
赋值 | stn |
数组取值和赋值
lod x
lod i
ixa elem_size(x)
如果是取值需要加上ind 0
对于x.i和x->i的区别在于一开始是lda x还是lod x
如果是取地址:
lod x 或者 lda x
lod field_offset(x, i)
ixa 1
如果是取值
lod x 或者lda x
ind field_offset(x,i)
p-code if(E) S1 else S2
if 有2两个标签2个jump
计算E
fjp L1
S1
ujp L2
Lab L1
S2
Lab L2
p-code if(E) S1,
一个标签一个jump
计算E
fjp L1
S1
Lab L1
while(E) S
while有两个标签两个jump
while开始先声明一个标签
Lab L1
计算E
fjp L2
S
ujp L1
Lab L2
f(int x, int y) { return x+y }
ent f
lod x
lod y
adi
ret
f(2+3, 4)
一开始用mst声明
然后将f看成一个根节点
mst
ldc 2
ldc 3
adi
ldc 4
cup f