【ARM】跳轉指令

00. 目錄

01. 跳轉指令概述

跳轉(B)和跳轉連接(BL)指令是改變指令執行順序的標準方式。ARM 一般按照字地址順序執行指令,需要時使用條件執行跳過某段指令。只要程序必須偏離順序執行,就要使用控制流指令來修改程序計數器。儘管在特定情況下還有其他幾種方式實現這個目的,但轉移和轉移連接指令是標準的方式。跳轉指令改變程序的執行流程或者調用子程序。這種指令使得一個程序可以使用子程序、if-then-else 結構及循環。執行流程的改變迫使程序計數器(PC)指向一個新的地址,ARMv5 架構指令集包含的跳轉指令如表 3-12 所示
在這裏插入圖片描述

另一種實現指令跳轉的方式是通過直接向 PC 寄存器中寫入目標地址值,實現在 4GB地址空間中任意跳轉,這種跳轉指令又稱爲長跳轉。如果在長跳轉指令之前使用“MOVLR”或“MOV PC”等指令,可以保存將來返回的地址值,也就實現了在 4GB 的地址空間中的子程序調用。

02. 跳轉指令 B 及帶連接的跳轉指令 BL

跳轉指令 B 使程序跳轉到指定的地址執行程序。帶連接的跳轉指令 BL 將下一條指令的地址複製到 R14(即返回地址連接寄存器 LR)寄存器中,然後跳轉到指定地址運行程序。需要注意的是,這兩條指令和目標地址處的指令都要屬於 ARM 指令集。兩條指令都可以根據 CPSR 中的條件標誌位的值決定指令是否執行。

2.1 B/BL指令的語法格式

B{L}{<cond>} <target_address>

BL 指令用於實現子程序調用。子程序的返回可以通過將 LR 寄存器的值複製到 PC 寄存器來實現。下面 3 種指令可以實現子程序返回。
① BX R14(如果體系結構支持 BX 指令)。
② MOV PC,R14。
③ 當子程序在入口處使用了壓棧指令:

STMFD R13!,{<registers>,R14}

可以使用指令:

LDMFD R13!,{<registers>,PC}

將子程序返回地址放入 PC 中。
ARM 彙編器通過以下步驟計算指令編碼中的 signed_immed_24。
① 將 PC 寄存器的值作爲本跳轉指令的基地址值。
② 從跳轉的目標地址中減去上面所說的跳轉的基地址,生成字節偏移量。由於 ARM指令是字對齊的,該字節偏移量爲 4 的倍數。
③ 當上面生成的字節偏移量超過−33 554 432~+33 554 430 時,不同的彙編器使用不同的代碼產生策略。否則,將指令編碼字中的 signed_immed_24 設置成上述字節偏移量的bits[25:2]。

2.2 應用示例

① 程序跳轉到 LABLE 標號處。

B LABLE ;
ADD R1,R2,#4
ADD R3,R2,#8
SUB R3,R3,R1
LABLE:
SUB R1,R2,#8

② 跳轉到絕對地址 0x1234 處。

B 0x1234

③ 跳轉到子程序 func 處執行,同時將當前 PC 值保存到 LR 中。

BL func

④ 條件跳轉:當 CPSR 寄存器中的 C 條件標誌位爲 1 時,程序跳轉到標號 LABLE 處執行。

BCC LABLE

⑤ 通過跳轉指令建立一個無限循環。

LOOP:
ADD R1,R2,#4
ADD R3,R2,#8
SUB R3,R3,R1
B LOOP

⑥ 通過使用跳轉使程序體循環 10 次。

MOV R0,#10
LOOP:
SUBS R0,#1
BNE LOOP

⑦ 條件子程序調用示例。

…
CMP R0,#5 ;如果 R0<5
BLLT SUB1 ;則調用
BLGE SUB2 ;否則調用 SUB2

03. 帶狀態切換的跳轉指令 BX

帶狀態切換的跳轉指令(BX)使程序跳轉到指令中指定的參數 Rm 指定的地址執行程序,Rm 的第 0 位複製到 CPSR 中 T 位,bit[31∶1]移入 PC。若 Rm 的 bit[0]爲 1,則跳轉時自動將CPSR中的標誌位T置位,即把目標地址的代碼解釋爲Thumb代碼;若Rm的位bit[0]爲 0,則跳轉時自動將 CPSR 中的標誌位 T 復位,即把目標地址代碼解釋爲 ARM 代碼。

3.1 指令格式

BX{<cond>} <Rm>

① 當 Rm[1∶0]=0b10 時,指令的執行結果不可預知。因爲在 ARM 狀態下,指令是 4字節對齊的。
② PC 可以作爲 Rm 寄存器使用,但這種用法不推薦使用。當 PC 作爲使用時,指令“BX PC”將程序跳轉到當前指令下面第二條指令處執行。雖然這樣跳轉可以實現,但最好使用下面的指令完成這種跳轉。

MOV PC, PC
# 或
ADD PC, PC, #0

3.2 指令應用示例

① 轉移到 R0 中的地址,如果 R0[0]=1,則進入 Thumb 狀態。

BX R0;

② 跳轉到 R0 指定的地址,並根據 R0 的最低位來切換處理器狀態。

ADRL R0,ThumbFun+1 ;
BX R0;

04. 帶連接和狀態切換的連接跳轉指令 BLX

帶連接和狀態切換的跳轉指令(Branch with Link eXchange,BLX)使用標號,用於使程序跳轉到 Thumb 狀態或從 Thumb 狀態返回。該指令爲無條件執行指令,並用分支寄存器的最低位來更新 CPSR 中的 T 位,將返回地址寫入到連接寄存器 LR 中。

4.1 指令格式

BLX <target_add>

其中,<target_add>爲指令的跳轉目標地址。該地址根據以下規則計算。

① 將指令中指定的 24 位偏移量進行符號擴展,形成 32 位立即數。
② 將結果左移兩位。
③ 位 H(bit[24])加到結果地址的第一位(bit[1])。
④ 將結果累加進程序計數器(PC)中。
計算偏移量的工作一般由 ARM 彙編器來完成。這種形式的跳轉指令只能實現−32~32MB 空間的跳轉。左移兩位形成字偏移量,然後將其累加進程序計數器(PC)中。這時,程序計數器的內容爲 BX 指令地址加 8 字節。位 H(bit[24])也加到結果地址的第一(bit[1]),使目標地址成爲半字地址,以執行接下來的 Thumb 指令。計算偏移量的工作一般由 ARM 彙編器來完成。這種形式的跳轉指令只能實現−32~32MB 空間的跳轉。

4.2 應用示例

① 從 Thumb 狀態返回到 ARM 狀態,使用 BX 指令。

BX R14

② 可以在子程序的入口和出口增加棧操作指令。

PUSH {<registers>,R14}
POP {<registers>,PC}

05. 附錄

11.1 ARM Architecture Reference Manual

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章