jalr $ a0,$ a0&#39 ;?的正确行为是什么?

时间:2014-04-22 17:08:07

标签: mips mips32 spim mars-simulator

我遇到了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似乎做了oppsite:首先跳转,然后将$t0的值设置为(前一个)pc + 4;因此调用func并照常运行。

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

2 个答案:

答案 0 :(得分:3)

来自Imagination Technologies' The MIPS32® Instruction Set v5.03为了清晰起见而增加了重点(registration required for download of the whole document

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

限制:

     

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

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

答案 1 :(得分:1)

MIPS instruction spec说:

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是错误的。