【ARM】跳转指令
00. 目錄
文章目錄
- 00. 目錄
- 01. 跳轉(zhuǎn)指令概述
- 02. 跳轉(zhuǎn)指令 B 及帶連接的跳轉(zhuǎn)指令 BL
- 2.1 B/BL指令的語法格式
- 2.2 應(yīng)用示例
- 03. 帶狀態(tài)切換的跳轉(zhuǎn)指令 BX
- 3.1 指令格式
- 3.2 指令應(yīng)用示例
- 04. 帶連接和狀態(tài)切換的連接跳轉(zhuǎn)指令 BLX
- 4.1 指令格式
- 4.2 應(yīng)用示例
- 05. 附錄
01. 跳轉(zhuǎn)指令概述
跳轉(zhuǎn)(B)和跳轉(zhuǎn)連接(BL)指令是改變指令執(zhí)行順序的標(biāo)準(zhǔn)方式。ARM 一般按照字地址順序執(zhí)行指令,需要時(shí)使用條件執(zhí)行跳過某段指令。只要程序必須偏離順序執(zhí)行,就要使用控制流指令來修改程序計(jì)數(shù)器。盡管在特定情況下還有其他幾種方式實(shí)現(xiàn)這個(gè)目的,但轉(zhuǎn)移和轉(zhuǎn)移連接指令是標(biāo)準(zhǔn)的方式。跳轉(zhuǎn)指令改變程序的執(zhí)行流程或者調(diào)用子程序。這種指令使得一個(gè)程序可以使用子程序、if-then-else 結(jié)構(gòu)及循環(huán)。執(zhí)行流程的改變迫使程序計(jì)數(shù)器(PC)指向一個(gè)新的地址,ARMv5 架構(gòu)指令集包含的跳轉(zhuǎn)指令如表 3-12 所示
另一種實(shí)現(xiàn)指令跳轉(zhuǎn)的方式是通過直接向 PC 寄存器中寫入目標(biāo)地址值,實(shí)現(xiàn)在 4GB地址空間中任意跳轉(zhuǎn),這種跳轉(zhuǎn)指令又稱為長(zhǎng)跳轉(zhuǎn)。如果在長(zhǎng)跳轉(zhuǎn)指令之前使用“MOVLR”或“MOV PC”等指令,可以保存將來返回的地址值,也就實(shí)現(xiàn)了在 4GB 的地址空間中的子程序調(diào)用。
02. 跳轉(zhuǎn)指令 B 及帶連接的跳轉(zhuǎn)指令 BL
跳轉(zhuǎn)指令 B 使程序跳轉(zhuǎn)到指定的地址執(zhí)行程序。帶連接的跳轉(zhuǎn)指令 BL 將下一條指令的地址復(fù)制到 R14(即返回地址連接寄存器 LR)寄存器中,然后跳轉(zhuǎn)到指定地址運(yùn)行程序。需要注意的是,這兩條指令和目標(biāo)地址處的指令都要屬于 ARM 指令集。兩條指令都可以根據(jù) CPSR 中的條件標(biāo)志位的值決定指令是否執(zhí)行。
2.1 B/BL指令的語法格式
B{L}{<cond>} <target_address>BL 指令用于實(shí)現(xiàn)子程序調(diào)用。子程序的返回可以通過將 LR 寄存器的值復(fù)制到 PC 寄存器來實(shí)現(xiàn)。下面 3 種指令可以實(shí)現(xiàn)子程序返回。
① BX R14(如果體系結(jié)構(gòu)支持 BX 指令)。
② MOV PC,R14。
③ 當(dāng)子程序在入口處使用了壓棧指令:
可以使用指令:
LDMFD R13!,{<registers>,PC}將子程序返回地址放入 PC 中。
ARM 匯編器通過以下步驟計(jì)算指令編碼中的 signed_immed_24。
① 將 PC 寄存器的值作為本跳轉(zhuǎn)指令的基地址值。
② 從跳轉(zhuǎn)的目標(biāo)地址中減去上面所說的跳轉(zhuǎn)的基地址,生成字節(jié)偏移量。由于 ARM指令是字對(duì)齊的,該字節(jié)偏移量為 4 的倍數(shù)。
③ 當(dāng)上面生成的字節(jié)偏移量超過?33 554 432~+33 554 430 時(shí),不同的匯編器使用不同的代碼產(chǎn)生策略。否則,將指令編碼字中的 signed_immed_24 設(shè)置成上述字節(jié)偏移量的bits[25:2]。
2.2 應(yīng)用示例
① 程序跳轉(zhuǎn)到 LABLE 標(biāo)號(hào)處。
B LABLE ; ADD R1,R2,#4 ADD R3,R2,#8 SUB R3,R3,R1 LABLE: SUB R1,R2,#8② 跳轉(zhuǎn)到絕對(duì)地址 0x1234 處。
B 0x1234③ 跳轉(zhuǎn)到子程序 func 處執(zhí)行,同時(shí)將當(dāng)前 PC 值保存到 LR 中。
BL func④ 條件跳轉(zhuǎn):當(dāng) CPSR 寄存器中的 C 條件標(biāo)志位為 1 時(shí),程序跳轉(zhuǎn)到標(biāo)號(hào) LABLE 處執(zhí)行。
BCC LABLE⑤ 通過跳轉(zhuǎn)指令建立一個(gè)無限循環(huán)。
LOOP: ADD R1,R2,#4 ADD R3,R2,#8 SUB R3,R3,R1 B LOOP⑥ 通過使用跳轉(zhuǎn)使程序體循環(huán) 10 次。
MOV R0,#10 LOOP: SUBS R0,#1 BNE LOOP⑦ 條件子程序調(diào)用示例。
… CMP R0,#5 ;如果 R0<5 BLLT SUB1 ;則調(diào)用 BLGE SUB2 ;否則調(diào)用 SUB203. 帶狀態(tài)切換的跳轉(zhuǎn)指令 BX
帶狀態(tài)切換的跳轉(zhuǎn)指令(BX)使程序跳轉(zhuǎn)到指令中指定的參數(shù) Rm 指定的地址執(zhí)行程序,Rm 的第 0 位復(fù)制到 CPSR 中 T 位,bit[31∶1]移入 PC。若 Rm 的 bit[0]為 1,則跳轉(zhuǎn)時(shí)自動(dòng)將CPSR中的標(biāo)志位T置位,即把目標(biāo)地址的代碼解釋為Thumb代碼;若Rm的位bit[0]為 0,則跳轉(zhuǎn)時(shí)自動(dòng)將 CPSR 中的標(biāo)志位 T 復(fù)位,即把目標(biāo)地址代碼解釋為 ARM 代碼。
3.1 指令格式
BX{<cond>} <Rm>① 當(dāng) Rm[1∶0]=0b10 時(shí),指令的執(zhí)行結(jié)果不可預(yù)知。因?yàn)樵?ARM 狀態(tài)下,指令是 4字節(jié)對(duì)齊的。
② PC 可以作為 Rm 寄存器使用,但這種用法不推薦使用。當(dāng) PC 作為使用時(shí),指令“BX PC”將程序跳轉(zhuǎn)到當(dāng)前指令下面第二條指令處執(zhí)行。雖然這樣跳轉(zhuǎn)可以實(shí)現(xiàn),但最好使用下面的指令完成這種跳轉(zhuǎn)。
3.2 指令應(yīng)用示例
① 轉(zhuǎn)移到 R0 中的地址,如果 R0[0]=1,則進(jìn)入 Thumb 狀態(tài)。
BX R0;② 跳轉(zhuǎn)到 R0 指定的地址,并根據(jù) R0 的最低位來切換處理器狀態(tài)。
ADRL R0,ThumbFun+1 ; BX R0;04. 帶連接和狀態(tài)切換的連接跳轉(zhuǎn)指令 BLX
帶連接和狀態(tài)切換的跳轉(zhuǎn)指令(Branch with Link eXchange,BLX)使用標(biāo)號(hào),用于使程序跳轉(zhuǎn)到 Thumb 狀態(tài)或從 Thumb 狀態(tài)返回。該指令為無條件執(zhí)行指令,并用分支寄存器的最低位來更新 CPSR 中的 T 位,將返回地址寫入到連接寄存器 LR 中。
4.1 指令格式
BLX <target_add>其中,<target_add>為指令的跳轉(zhuǎn)目標(biāo)地址。該地址根據(jù)以下規(guī)則計(jì)算。
① 將指令中指定的 24 位偏移量進(jìn)行符號(hào)擴(kuò)展,形成 32 位立即數(shù)。
② 將結(jié)果左移兩位。
③ 位 H(bit[24])加到結(jié)果地址的第一位(bit[1])。
④ 將結(jié)果累加進(jìn)程序計(jì)數(shù)器(PC)中。
計(jì)算偏移量的工作一般由 ARM 匯編器來完成。這種形式的跳轉(zhuǎn)指令只能實(shí)現(xiàn)?32~32MB 空間的跳轉(zhuǎn)。左移兩位形成字偏移量,然后將其累加進(jìn)程序計(jì)數(shù)器(PC)中。這時(shí),程序計(jì)數(shù)器的內(nèi)容為 BX 指令地址加 8 字節(jié)。位 H(bit[24])也加到結(jié)果地址的第一(bit[1]),使目標(biāo)地址成為半字地址,以執(zhí)行接下來的 Thumb 指令。計(jì)算偏移量的工作一般由 ARM 匯編器來完成。這種形式的跳轉(zhuǎn)指令只能實(shí)現(xiàn)?32~32MB 空間的跳轉(zhuǎn)。
4.2 應(yīng)用示例
① 從 Thumb 狀態(tài)返回到 ARM 狀態(tài),使用 BX 指令。
BX R14② 可以在子程序的入口和出口增加棧操作指令。
PUSH {<registers>,R14} POP {<registers>,PC}05. 附錄
11.1 ARM Architecture Reference Manual
總結(jié)
- 上一篇: 【ARM】Load Store指令
- 下一篇: 【ARM】MRS MSR指令