C声明
A= A? C[0] : B;
以这种方式写汇编指令是否正确?
假设数组C的$t1=A, $t2=B, $s1=base
地址:
beq $t1, $0, ELSE
lw $t1, 0($s1)
ELSE: add $t1, $t2, $0
答案 0 :(得分:3)
不,它似乎不正确,因为 items newitem freq
1: BA31C1CC63E5043483FAE25F085E25E5 INSERT OV1 0.1666667
2: BECE6374D91D47E6285EFDEBA6D65BB9 DATABASE OV2 0.1666667
3: 26D695C8CA82CAFFDF985201F3AA44D7 UPDATE OV3 0.3333333
4: 2BC5A4199A0DDA16FA17A9CA1AA17C02 DATABASE OV4 0.1666667
5: 6D944D54C54ED75D487288FE1505BB59 INSERT OV5 0.1666667
即使add $t1, $t2, $0
也会被执行。
我希望这有效(未经测试):
$t1 != $0
此代码假定 beq $t1, $0, ELSE
sll $0, $0, 0 # NOP : avoid the instruction after branch being executed
lw $t1, 0($s1)
j END
sll $0, $0, 0 # NOP : avoid the instruction after branch being executed
ELSE: add $t1, $t2, $0
END:
的元素各为4字节长。
答案 1 :(得分:0)
您可以避免使用无条件j
。不要将其构造为if / else,而是始终执行A = B(因为复制寄存器比跳转便宜),然后可选地执行加载。
在带分支延迟插槽的MIPS 上,延迟插槽实际帮助我们:
# $t1=A, $t2=B, $s1=base
beq $t1, $zero, noload
move $t1, $t2 # branch delay: runs always
lw $t1, 0($s1)
noload:
# A= A? C[0] : B;
在 MIPS 没有分支延迟插槽(如默认配置中的MARS或SPIM)中:
# MIPS without branch-delay slots
# $t1=A, $t2=B, $s1=base
move $t3, $t1 # tmp=A
move $t1, $t2 # A=B
beq $t3, $zero, noload # test the original A
lw $t1, 0($s1)
noload:
# $t1 = A= A ? C[0] : B;
如果我们可以破坏B并重新安排寄存器,我们可以在没有分支延迟的情况下保存insn :
# MIPS without branch-delay slots
# $t1=A, $t2=B, $s1=base
beq $t1, $zero, noload
lw $t2, 0($s1)
noload:
# $t2 = A. B is "dead": we no longer have it in a register
BEQ之前的move $t3, $t2
可以在此序列之前将B保存在另一个寄存器中。结束不同寄存器中的变量可以保存指令,但却更难以跟踪事物。如果你正在展开循环,你可以在循环中解决这个问题,因为代码的第二个副本可以重新洗牌,以便以循环顶部所需的方式返回寄存器。
move x, y
是or x, y, $zero
或ori x, y, 0
的伪指令。或addu x, y, $zero
。无论你喜欢它,还是让你的汇编程序为你做这件事。
答案 2 :(得分:-1)
为C语句编写MIPS段
x=5; y=7;
Land(x,y,z) // z=x &y as procedure call
if (z>x) y=x+1