我正在学习 mips 中的管道,并被告知这两条指令:
jal addr;
store $ra;store the value of $ra into memory
会导致数据危害,但我不明白为什么。有人可以帮助我吗?
MIPS 分支延迟槽中的指令总是在分支执行之前完全执行。所以store $ra
指令将存储在指令更新之前$ra
存在的值。换句话说,这个序列:jal
$ra
li $ra, 0x1234
L: jal addr
nop
store $ra, mem # mem <- L + 8
将与此序列不同的值存储到内存中:
li $ra, 0x1234
jal addr
store $ra, mem # mem <- 0x1234
这不是 MIPS 架构中未定义的序列,因此结果是可预测的。
MIPS 汇编器通常会在设置了unlessnop
之后插入 a 。jal
noreorder
我不知道是什么store
,但 MIPS 上的所有正常分支和跳转指令都与紧随其后的指令一起执行。在大多数琐碎的情况下,您可能会认为分支/跳转是最后执行的,而其他指令是第一个执行的。
但是,如果成对的指令在内部几乎作为一条不可分割的指令而不是两条独立的指令执行,我不会感到惊讶。
这里的潜在问题是jal
存储在$ra
后面指令的地址中store
。如果store
或任何指令使用$ra
,则在两次访问之间可能存在竞争条件、数据危险(无论您如何称呼),$ra
最终结果可能无法确定,也可能不是人们可能天真的期望的那样。