试图了解如果输入为负则分支的MIPS函数

时间:2019-03-21 23:57:51

标签: assembly mips

我正在阅读以下有关汇编语言代码的摘录:

“可以在组装中使用标签代替计算分支和跳转指令的精确值。以下是示例。”

int isNeg(int a0) {
  if (a0 < 0) {
    return 1;
  } else {
    return 0;
  }
}

isNeg:
  slt  $t0 $a0 $0
  beq $t0 $0 isPos
  jr $ra
isPos:
  add $v0 $0 $0
  jr $ra

这就是我的解释方式(请根据我做的任何错误假设对我进行纠正):

isNeg:
  slt $t0 $a0 $0 // store ($a0 < 0) in $t0
  beq $t0 $0 isPos // if ($t0 == 0) branch by 0 bytes
  jr  $ra
isPos:
  add $v0 $0 $0 // store 0+0=0 in $v0
  jr  $ra

因此,如果我的假设在这里是正确的,则如果$ a为负,则不执行任何操作;如果$ a为正,则以0进行分支,等效于不执行任何操作。谁能对此有所启发?

1 个答案:

答案 0 :(得分:1)

  

有人能对此有所启发吗?

如果我理解正确,那么本文是从书中摘录的。该示例旨在显示某些指令的效果,而不是显示可以在真实程序中(例如,在具有MIPS CPU的WLAN路由器上)真正找到的“真实”代码。

这本书的作者唯一想展示的是标签的工作方式,因此他写了一个(愚蠢的)包含标签的示例。

  

如果$ a为负,我们什么也不做

正确(假设jr $ra在实际MIPS CPU中不是不是 delayed branch

我认为这本书的作者忘记了addi $v0 $0 -1指令。

beq $t0 $0 isPos
     

如果$ a为正,那么我们以0分支

如果beq delayed branch,这是正确的。

在这种情况下,CPU将首先在beqjr指令之后立即执行该指令,然后才实际进行分支/跳转。

但是,在这种情况下,在大多数实际的MIPS CPU上,紧随jr指令之后的beq指令是不允许的。因此,我认为这里不是这种情况。

如果使用的模拟器不模拟延迟时隙,则beq指令将跳4个字节(在jr指令上)。

如果使用真正的MIPS CPU和汇编器,则在每个跳转/分支指令(GNU中的nop选项)之后插入add $0 $0 $0(例如.set reorder)指令时,{{1} }指令将跳8个字节(在beq指令及其后的jr指令上方)。跳转之后,执行nop指令。