Weird MIPS assembler behavior with jump (and link) instruction

给你一囗甜甜゛ 提交于 2019-11-28 12:16:22

MIPS has explicit pipeline hazards; the instruction immediately following a branch or jump instruction will always be executed (this instruction is sometimes referred to as the "branch delay slot"). If your code was really assembled exactly as you wrote it:

__start:
   addi $a0, $0, 100
   addi $a1, $0, 200 
   jal test

test:
   add $v0, $a0, $a1
   jr $ra

then the add instruction would be executed twice around the time that the jal happens: once in the delay slot, and once on the following cycle when the program counter change has actually taken effect.

By default, the GNU assembler reorders instructions for you: it is clear that the second addi must always be executed, so it can be swapped with the jal instruction, so that the addi moves into the delay slot. (In cases where the assembler can't deduce that it is safe to do this, it will insert a nop into the delay slot instead.)

If you don't want it to do this reordering for you, add the directive

.set noreorder

at the top of your source file. You must deal with the hazards yourself in this case. If you do this, I recommend annotating the delay slots so that they stand out - e.g. by adding an extra space (or two) of indentation. For example:

.set noreorder

__start:
   addi $a0, $0, 100
   jal test
     addi $a1, $0, 200 

test:
   add $v0, $a0, $a1
   jr $ra
     nop
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!