我遇到了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
并照常运行。
我的问题是,在这种情况下,哪个模拟器实现了正确的行为?
答案 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)
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是错误的。