C三元条件运算符到MIPS汇编,一边从内存加载

时间:2015-11-01 07:43:11

标签: c assembly mips

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

3 个答案:

答案 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, yor x, y, $zeroori 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