MIPS分支而不是跳转

时间:2016-09-20 12:16:54

标签: assembly mips32

使用具有预定条件的分支的原因是什么,例如:

beq $0, $0, TEST

而不只是像这样使用跳跃?

j TEST

分支用于测试条件,但在这种情况下,分支的使用条件始终为true。那么为什么要跳过它?它以某种方式更快吗?

我偶然发现了answer,但我不知道这是否确实是我问题的正确答案,因为我对重新安置一无所知。

1 个答案:

答案 0 :(得分:1)

J指令的编码如下:

----------------------------
| opcode |   instr_index   |
----------------------------

instr_index是目标地址的最低有效28位,右移2以得到26位值。您最终跳转到的地址是(PC & 0xF0000000) | (instr_index << 2)

BEQ变体的编码如下:

-----------------------------
| opcode | 0 | 0 |  offset  |
-----------------------------

您最终分支到的地址是PC + sign_extend(offset << 2)

(注意,在两种情况下PC都是紧接在分支/跳转指令之后的指令的地址,而不是分支/跳转指令本身。)

现在,假设您有以下代码:

main:
j foo
nop
foo:

此代码原本打算在地址0x00400024加载。 foo的地址将为0x0040002cJ指令的编码为(2 << 26) | (0x0040002c >> 2) = 0x0810000b

但是您决定要重新定位此代码(将其复制到内存中的其他位置并在该位置执行)。假设您的代码现在正在0x00410000执行。在这种情况下,我们希望J指令跳转到0x00410008,但它仍会跳转到0x0040002c(0x00410004 & 0xF0000000) | (0x010000b << 2) = 0x0040002c)。

另一方面,如果您使用BEQ,则会使用说明字0x10000001(4 << 26) | (4 >> 2))。即使代码重新定位,您仍然会分支到正确的地址:0x00410004 + (1 << 2) = 0x00410008