4

我遇到了指令jalr $t1, $t2指令,它应该将 $t1 设置为返回地址并跳转到 $t2。然而,关于哪个操作首先发生似乎有些模糊。例如,以下在 MARS 和 SPIM 中的工作方式不同:

.text
main:
    la $t0, func
    jalr $t0, $t0
    # ...
    li $v0, 10
    syscall        # Exit program

func:
    # ...
    jr $t0

在 MARS 中,$t0首先设置为pc + 4(返回地址),然后跳转到$t0,这样下面的代码func就永远不会运行。然而,SPIM 似乎做了相反的事情:先跳转,然后将 value 设置$t0为 (the previous) pc + 4;因此func被调用并照常运行。

因此,我的问题是,在这种情况下哪个模拟器实现了正确的行为?

4

2 回答 2

3

来自 Imagination Technologies 的The MIPS32® Instruction Set v5.03重点是为了清晰起见(下载整个文档需要注册

Format: JALR rs (rd = 31 implied)  
        JALR rd, rs

限制:

寄存器说明符 rs 和 rd 不能相等,因为这样的指令在重新执行时没有相同的效果。执行这样一条指令的结果是不可预测的。此限制允许异常处理程序在分支延迟槽中发生异常时通过重新执行分支来恢复执行。))

换句话说,奇怪的是,它们都正确。

于 2014-04-22T17:52:19.233 回答
1

MIPS 指令规范说:

Operation:
    I:  temp ← GPR[rs]
        GPR[rd] ← PC + 8
    I+1:if Config1CA = 0 then
            PC ← temp
        else
            PC ← temp<sub>GPRLEN-1..1</sub> || 0
            ISAMode ← temp<sub>0</sub>
        endif

所以看起来 SPIM 是正确的,而 MARS 是错误的。

于 2014-04-22T17:41:15.547 回答