MIPS组装奇怪的跳跃

use*_*875 4 assembly mips

我可能在这里遗漏了一些非常明显的东西,但是我一直在重复这个问题而且我坚决地陷入困境.在下面的代码中,$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
Run Code Online (Sandbox Code Playgroud)

我必须承认我完全难过了.

Mat*_*ery 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
Run Code Online (Sandbox Code Playgroud)


Oli*_*rth 5

加法指令发生在分支延迟槽beq.

  • @ user472875:它们是流水线CPU的副作用.当CPU意识到它必须分支时,它已经加载了下一条指令,因此必须执行它. (4认同)
  • 一些汇编程序(例如GNU as)可以假装没有分支延迟槽:添加一个`.set reorder`指令,让汇编程序稍微移动指令或在必要时添加一个`nop`. (2认同)