從https://www.keil.com/support/man/docs/armasm/armasm_dom1361289866046.htm讀到arm-thumb 指令的blx指令可以支持最大 4MB 的跳轉范圍。
但據我所知,arm-thumb 指令只有 16 位長,那么 16 位怎么能包含 4MB 的偏移量呢?
uj5u.com熱心網友回復:
在原始 Thumb 指令集中,該BL指令包含兩條 16 位指令,編碼如下:
1111 HOOO OOOO OOOO BL <label>
| |
| \.. long branch and link offset high/low
\............... low/high offset
0 -- offset high
1 -- offset low
兩條指令中的第一條必須將 H 位設定為 0。11 位偏移量向左移動 12,添加PC并放入LR暫存器。
LR = PC (offset << 12)
兩條指令中的第二條必須將 H 位設定為 1。11 位偏移量左移 1,添加到LR暫存器的內容中,并用作分支目標。LR暫存器設定為回傳地址。
temp = next instruction address
PC = LR (offset << 1)
LR = temp | 1
在 ARMv5T 中,BLX添加了指令的 Thumb 編碼,允許 Thumb 代碼呼叫 ARM 代碼。BL這是通過在指令的后半部分*定義一個新的拇指位來完成的。
111T 1OOO OOOO OOOO BL/BLX <label> (second half)
| |
| \.. long branch link exchange offset low
\................. thumb bit
0 -- BLX is encoded
1 -- BL is encoded
的操作BLX類似于指令的后半部分BL,但偏移量必須是偶數。該函式在 ARM 狀態而不是 Thumb 狀態下呼叫。
temp = next instruction address
PC = (LR (offset << 1)) & 0xfffffffc
LR = temp | 1
CSPR T bit = 0
請注意,總共 22 個立即位給出半字偏移量,實作了觀察到的 ±4 MiB 的分支偏移量。
將這兩部分放在一起,我們還可以看到32 位指令BL,BLX其編碼如下:
1111 0OOO OOOO OOOO 111T 1OOO OOOO OOOO BL/BLX <label>
| | |
| | \.. 22 bit offset (low half)
| \................. thumb bit
\....................... 22 bit offset (high half)
在 Thumb2 中,該方案得到了擴展。 BL并BLX成為正確的 32 位指令,它們的一半必須連續給出。? 第二個指令字的某些位被定義為將分支偏移擴展到 ±16 MiB。
1111 0SOO OOOO OOOO 11AT BOOO OOOO OOOO BL/BLX <label>
| | || | |
| | || | \.. 21 bit offset (low half)
| | || \............... additional bit J2
| | |\................. thumb bit
| | \.................. additional bit J1
| \....................... 21 bit offset (high half)
\................................... sign bit
如果設定了拇指位,則對BL指令進行編碼。如果清晰,則對BLX指令進行編碼。在后一種情況下,21 位偏移量必須是偶數。然后分支偏移量計算如下:
I1 = !(J1 ^ S)
I2 = !(J2 ^ S)
imm32 = (S ? 0xffff << 24 : 0) | (I1 << 23) | (I2 << 22) | (imm21 << 1)
temp = next instruction address
PC = LR offset
LR = temp | 1
if thumb bit clear
CSPR T bit = 0
BL雖然編碼附加偏移位的方案一開始看起來很復雜,但它只是將兩個附加位編碼到分支偏移中的最簡單方法,同時與和BLX指令的現有編碼兼容。
請參閱ARM 體系結構參考手冊、ARMv7-A 和 ARMv7-R 版本、 ARM7TDMI資料表和 ARMv5 的ARM 體系結構參考手冊以進行進一步閱讀。
* 相關編碼1110 0OOO OOOO OOOO對16位無條件分支指令進行編碼B <label>。
BL? 在 Thumb2 之前,a或指令的兩個部分BLX是獨立的指令,可以與其他指令穿插甚至單獨發出,但強烈建議按順序發出。一條BL或BLX指令的兩半之間也可能發生中斷,從而使LR暫存器的臨時內容可觀察。在包括 ARMv6-M 在內的 Thumb2 目標上,這不再可能,BL并且BLX表現為 32 位指令。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/415416.html
標籤:
上一篇:NASM中的MOVZBQ等價物
