psuedo MIPS分支和链接命令

时间:2017-01-17 11:31:56

标签: assembly mips

我的最终目标是以这种方式用MIPS编写代码

temp = 0;
if (x == y)
   temp = 1
...rest of the program...

我应该为==,!=,< =,> =,< ,>

我想到了类似的东西:

li $t1 0
beq $r1 $r2 Temp1
/**rest of the program...**/

Temp1:
li $t1 1
(1) /** how do I return to rest of the program? **/

我在mips中看到BGEZAL命令(beq的insetad)允许我输入(1)行

jr $ra

但我没有找到适用于所有情况的适当命令:bge,bne,neq等。

我的问题:

所有案例制作此分支和链接的简单方法是什么?

我的意思是,如果发生了某种情况,请分支到标签,并将$ +的地址存储在$ ra中,以便我可以返回我的代码?

另外,我不能创建另一个标签来代表程序的其余部分(并跳转它),我必须在$ ra中以某种方式返回,因为它是从基于java的代码转换mips

感谢。

1 个答案:

答案 0 :(得分:4)

对于这个例子

temp = 0;
if (x == y)
   temp = 1
...rest of the program...

使用相反的分支更容易:

li    $t1, 0
bne   $r1, $r2, RestOfProgram  ; temp already is 0, so only continue
; here you want temp=1, because x==y, so just set it, and continue
li    $t1, 1
RestOfProgram:
...rest of the program...

所以你这样做:

temp = 0;
if (x != y) goto rest_of_program
temp = 1
rest_of_program:
...rest of the program...

(它是丑陋的伪C,但在ASM中这是更优雅和干净的方式,因为" goto"是ASM的操作方式,而有条件地执行某些指令则是针对ASM的"在这里我有pc集,所以我会执行它")。

但你根本不需要分支(如果你的目标是根据条件将某个寄存器设置为0或1),例如:

temp = (x < y);
slt    $t1, $r1, $r2    ; or "sltu" for unsigned values

temp = (x > y)
slt    $t1, $r2, $r1    ; or "sltu" for unsigned values

EDIT2(我确实错过了&lt; =,&gt; =,... by pseudo ins的存在并且产生了不太好的部分答案,现在编辑它以更准确和完整):

还有伪指令sle / sge / seq / sne for&lt; =,&gt; =,==,!=。

出于我自己的好奇心,我不得不看看它们是如何实现的,基本上是:

sgt: temp = (y < x)   (slt with swapped arguments)
sle: temp = !(y < x)  (slt, xori)
sge: temp = !(x < y)  ("sle" with swapped arguments)
seq: temp = |x - y| < 1  (subu, $at=1, sltu)
sne: temp = 0 < |x - y|  (subu, sltu $zero)

EDIT1:如果你坚持使用较慢的$ ra子程序,那么将整个测试移到Temp1:

li  $t1, 0
jal Temp1_when_equal
... rest of code ...

Temp1_when_equal:      ; will set $t1 to 1 when $r1 == $r2
bne $r1, $r2, Temp1_keep_0
li  $t1, 1
Temp1_keep_0:
jr  $ra

但我不清楚为什么你可以做这个,并且不能做正确的事情,看起来很奇怪,你可能有一些非常奇怪的情况(基本上我不相信你,你可能错过了如何在没有标签的注入代码中进行分支的方式,所以你认为它不可能,但只要你注入代码就可以了就像在你的问题中一样,你也可以在注入短代码的范围内注入&#34;其余代码&#34; target。

如果你真的必须这样做,那么考虑将它全部移动到子程序,因此主代码只有jal set_t1_when_r1_equals_r2,并且li都将在子程序中。这至少有点可维护,上面的例子非常糟糕。

但&#34;由条件设置&#34;当然,解决方案优于任何分支。