我可能在这里遗漏了一些非常明显的东西,但我一遍又一遍地重复着这个问题,而且我肯定会陷入困境。在下面的代码中,$8
仅在$2 != $0
时递增。现在我进行了双重和三重检查并且beq
指令有效(例如,如果我将lop更改为end2,它确实会去那里)。
但是,由于某种原因,$8
无论如何都会递增,即使分支已执行。
lop: beq $3, $0, end2
and $2, $3, $4
sll $3, $3, 1
beq $2, $0, lop
addi $8, $8, 1
j lop
我必须承认我完全被难倒了。
答案 0 :(得分:6)
(第一个and
之后的beq
也将始终执行。)
MIPS存在明确的管道危害;当决定分支(或不分支)时,以下指令已经通过指令管道进展得足够远,无论如何都将执行。这被称为“分支延迟时隙”。
在某些情况下,您可以安排代码来利用这一点;如果你不能(或不想),你可以在下面的指令中加上nop
。
有些汇编程序会为您重新排序代码(或填写nop
) - 例如gas
,GNU汇编程序,除非你告诉它不要使用.set noreorder
指令。但无论如何,你仍然需要在拆卸时注意它。
如果您在没有自动重新排序的情况下编写代码,我建议使用一些额外的缩进来注释延迟槽以使其脱颖而出:
lop: beq $3, $0, end2
nop
and $2, $3, $4
sll $3, $3, 1
beq $2, $0, lop
nop
addi $8, $8, 1
j lop
答案 1 :(得分:5)
添加说明发生在beq
的{{3}}。