什麼是使用分支規定的條件的原因,像這樣的:MIPS分支,而不是跳躍
beq $0, $0, TEST
而不是僅僅使用這樣的跳躍?
j TEST
分支用於測試條件,但在這種情況下,分支已被使用的條件將始終爲真。那麼爲什麼跳過它呢?它有點快嗎?
我遇到了這個answer,但我不知道這是否確實是我的問題的正確答案,因爲我還不知道有關重定位的任何信息。
什麼是使用分支規定的條件的原因,像這樣的:MIPS分支,而不是跳躍
beq $0, $0, TEST
而不是僅僅使用這樣的跳躍?
j TEST
分支用於測試條件,但在這種情況下,分支已被使用的條件將始終爲真。那麼爲什麼跳過它呢?它有點快嗎?
我遇到了這個answer,但我不知道這是否確實是我的問題的正確答案,因爲我還不知道有關重定位的任何信息。
的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
的地址將爲0x0040002c
,J
指令將編碼爲(2 << 26) | (0x0040002c >> 2)
= 0x0810000b
。
但是,您決定要重新定位此代碼(將其複製到內存中的其他位置並在該位置執行)。假設您的代碼現在正在執行0x00410000
。在這種情況下,我們希望J
指令跳轉到0x00410008
,但它仍將跳轉到0x0040002c
((0x00410004 & 0xF0000000) | (0x010000b << 2)
= 0x0040002c
)。
如果另一方面您使用了BEQ
,那麼您將得到指令字0x10000001
((4 << 26) | (4 >> 2)
)。即使代碼被重新定位,您仍然會分支到正確的地址:0x00410004 + (1 << 2)
= 0x00410008
。