试图理解这个MIPS函数,如果它的输入为负,则分支

问题描述 投票:0回答:1

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

“标签可用于组装,以替换[sic]计算分支和跳转指令的精确值。以下是一个例子。”

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分支,这相当于什么都不做。任何人都可以对此有所了解吗?

assembly mips
1个回答
1
投票

任何人都可以对此有所了解吗?

如果我理解正确,这个文本来自一本书。示例是显示某些指令的效果,而不是显示真正可以在实际程序中找到的“真实”代码(例如,在具有MIPS CPU的WLAN路由器上)。

这本书的作者唯一想要展示的是标签是如何工作的,所以他写了一个包含一些标签的(愚蠢的)例子。

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

正确(假设jr $ra不是真正的MIPS CPU中的delayed branch

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

beq $t0 $0 isPos

如果$ a是正数,那么我们将0分支

如果beqdelayed branch,这将是正确的。

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

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

如果使用不模拟延迟槽的仿真器,则beq指令将跳过4个字节(通过jr指令)。

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

© www.soinside.com 2019 - 2024. All rights reserved.