ARM指令系統(tǒng)特點(diǎn)
ARM指令系統(tǒng)屬于RISC指令系統(tǒng)。標(biāo)準(zhǔn)的ARM指令每條都是32位長(zhǎng),有些ARM核還可以執(zhí)行Thmub指令集,該指令集是ARM指令集的子集,每條指令只有16位。
1 數(shù)據(jù)類型
ARM處理器一般支持下列6種數(shù)據(jù)類型:
l8位有符號(hào)字節(jié)類型數(shù)據(jù);
l8位無(wú)符號(hào)字節(jié)類型數(shù)據(jù);
l16位有符號(hào)半字類型數(shù)據(jù);
l16位無(wú)符號(hào)半字類型數(shù)據(jù);
l32位有符號(hào)字類型數(shù)據(jù);
l32位無(wú)符號(hào)字類型數(shù)據(jù);
有些ARM處理器不支持半字和有符號(hào)字節(jié)數(shù)據(jù)類型。在ARM內(nèi)部,所有指令都是32操作數(shù)據(jù)。短的數(shù)據(jù)數(shù)據(jù)類型只有在數(shù)據(jù)傳送類指令中才被支持當(dāng)1個(gè)字節(jié)數(shù)據(jù)取出后,被擴(kuò)展到32位,在內(nèi)部數(shù)據(jù)處理時(shí),作為32位的什進(jìn)行處理,并且ARM指令以字為邊界。所有Thumb指令都是16位指令時(shí),并且以2個(gè)字節(jié)為邊界。
ARM協(xié)處理器可以支持另外的數(shù)據(jù)類型,包括一套浮點(diǎn)數(shù)據(jù)類型,ARM的核并沒(méi)有明確的支持。
2 存儲(chǔ)器組織
圖3-1所示為存儲(chǔ)器組織。
ARM這的地址的低三下四位必須為00,半字地址的最低位為0。字的內(nèi)容在存儲(chǔ)器中的存放通常有兩種方式,即小端(little-endian)和大端(big-endian),這兩種方式的不同在于最低位字節(jié)的地址是否在最高位字節(jié)的地址之前。小端方式每個(gè)字的低位字節(jié)在后,例如0x12345678小端方式存放如下:
地址 內(nèi)容
A 78
A+1 56
A+2 34
A+3 12
大端方式的存放如下:
地址 內(nèi)容
A 12
A+1 34
A+2 56
A+3 78
大多數(shù)的ARM處理器芯片都不得可以支持上面兩種方式,一般缺省為小端。
23222120
19181716
word16
15141312
half-world12 half-word14
111098
word8
7654
byte6 half-word4
3210
byte3 byte2 byte1 byte0
20212223
16171819
word16
12131415
half-world12 half-word14
891011
word8
4567
Byte5 half-word6
0123
Byte0 byte1 byte2 byte3
(a)小端存儲(chǔ)器組織 (b)大端存儲(chǔ)器組織
圖3-1 存儲(chǔ)器組織
3 ARM指令特點(diǎn)
1.每條指令的多功能
ARM指令一個(gè)重要的特點(diǎn)是它所有的指令都帶有條件,例如用戶可以測(cè)試某個(gè)寄存器的什但是直到下次使用同一條件進(jìn)行測(cè)試時(shí),才能有條件的執(zhí)行這些指令。ARM指令另一個(gè)重要的特點(diǎn)是具有靈活的第2操作數(shù),既可以是立即數(shù),也可以是邏輯運(yùn)算數(shù),使得ARM指令可以在讀取數(shù)值的同時(shí)進(jìn)行算術(shù)和移位操作。它可以在幾種模式下操作,包括通過(guò)使用SWI(軟件中斷)指令從用戶模式進(jìn)入系統(tǒng)模式。
2. 協(xié)處理器的作用
ARM內(nèi)核可以提供協(xié)處理器指令接口,通過(guò)擴(kuò)展協(xié)處理器完成復(fù)雜的功能,因此,ARM指令還包含了多條協(xié)處理器接口,使用多達(dá)16個(gè)協(xié)處理器;允許將其他處理器能過(guò)協(xié)處理器接口進(jìn)行耦合;還包括幾種內(nèi)豐管理單元的變種;包括簡(jiǎn)單的內(nèi)存保護(hù)到復(fù)雜的內(nèi)存保護(hù)到復(fù)雜的頁(yè)面層次。例如,管理存儲(chǔ)部件MMU就是ARM內(nèi)核通過(guò)協(xié)處理器CP15實(shí)現(xiàn)對(duì)內(nèi)存的管理。
3. Thumb指令
ARM有兩種指令集:16位Thumb指令集和32位ARN指令集。使用16位的存儲(chǔ)器可以降低成本,在這種情況下,Thumb指令集的整體執(zhí)行速度比32位指令集快,而且提高了代碼密度,所以一般用Thumb編譯器將C語(yǔ)言程序編譯成16位的代碼。處理器一開始總在arm狀態(tài),可使用BX指令轉(zhuǎn)換到Thumb狀態(tài)。
4. 具有RISC指令的特點(diǎn)
由于ARM指令屬于RISC指令,所以具有RISC指令的特點(diǎn),指令少,且等長(zhǎng),便于充分利用流水線技術(shù);使用多寄存器,且多為簡(jiǎn)單的Load與Store指令(從內(nèi)存中讀取某個(gè)值,執(zhí)行完操作后再將其放回內(nèi)存)。
5. 立即數(shù)和直接地址
由于指令統(tǒng)一為32位,無(wú)法在1條指令中存放32位立即數(shù)。一般立即數(shù)為5~12位。采用一些特殊的方法,使它能處理立即數(shù)。
同理,直接(或相對(duì))地址一般為24位,但由于指令地址的低2位為00,故尋地范圍為±226,相對(duì)地址為±225。
3.2 ARM指令系統(tǒng)
3.2.1 ARM指令的尋址方式
每條ARM指令都是32位指令,在大多數(shù)情況下,可以有3個(gè)操作數(shù),其中第1個(gè)操作數(shù)或目的操作數(shù)一般為基本操作數(shù)方式。ARM指令的基本尋址方式有:
l寄存器尋址
例:
ADD R0,R1,R2 ;(R1)+(R2)→R0
l立即數(shù)尋址
例:
ADD R3,R3,#2 ;(R3)+2→R3
l寄存器間接尋址
例:
LDR R0,R0,[R3] ;((R3))→R0
l寄存器變址
例:
LDR R0,[R1,#4] ;((R1)+4)→R0
l相對(duì)尋址
例:
B rel ;(PC)+rel→PC
另外,每條ARM指令中還可以有第2條和第3條操作數(shù),它們采用復(fù)合尋址方式,ARM的復(fù)合尋址方式有5種。
1 第2操作數(shù)的尋址方式
ARM運(yùn)算指令和某些數(shù)據(jù)傳送指令除了目的操作數(shù)和第1個(gè)操作數(shù)(它們?yōu)榧拇嫫鲗ぶ罚┩猓€具有第2操作數(shù)。該第2操作數(shù)具有以下尋址方式:
?。?)立即尋址(#immediate_8*r*2)
由8位立即數(shù)和4位移位位r決定。R指定左移rⅹ2位,r=0~15,實(shí)際上可移位0,2,4,6,···,28,30。例如:實(shí)際的立即數(shù)可以為0xFF(r=0),0xFF0(r=2),0xFF000000(r=12), 0xFF000000F(r=14)等。
例:
MOV R0,#20
?。?)寄存器直接(Rm)
例:
MOV R0,R1
?。?)寄存器移位(Rm,移位碼#immed_5)
移位碼包括:LSL、LSR、ASR、ROR、RPX的任何一種,移位位數(shù)由#immed_5決定。詳細(xì)請(qǐng)見(jiàn)ARM數(shù)據(jù)處理類指令的第2操作數(shù)。
例:
MOV R0,R1,LSL #1 ;(R1)*2→R0
(4)寄存器間接移位(Rm,移位碼Rs)
移位碼包括:LSL、LSR、ASR、ROR,移位位數(shù)由Rs的內(nèi)容決定。
例:
MOV R0,R1,R2,LSL,R2 ;(R1)*(R2)→R0
2 字和無(wú)符號(hào)字節(jié)尋址方式
ARM中的取數(shù)指令的源操作數(shù)和存數(shù)指令的目的操作數(shù)采用帶偏移量的變址方式,可以表示為基址+變址尋址。有效地址寄存器的內(nèi)容加上偏移量的值。對(duì)于字和無(wú)符號(hào)字節(jié),尋址方式通??梢园?種:寄存器間接尋址,前變址偏移尋址和后變址偏移尋址。帶偏移量的變址包括常數(shù)蔌寄存器值。
(1)存器間接尋址)[Rn])
例:
LDR R0,[R1] ;((R1))→R0
STR R0,[R1] ;(R0)→(R1)
(2)前變址偏移尋址([Rn,偏移量]{!})
在數(shù)據(jù)傳送之前,瘵偏移量加到Rn中。其結(jié)果作為傳送數(shù)據(jù)的存儲(chǔ)器地址。若使用后綴“!”,則結(jié)果寫回到Rn中,Rn不允許是R15。
該尋址方式又分為下列3種:
?、倭⒓磾?shù)偏移尋址[Rn,#±《immed_12》]{!}
例:
LDR R0,[R1,#5]! ;((R1+5)→R0,(R1)+5→R1
?、诩拇嫫髌疲跼n,#±Rm{!}
例
LDR R0,[R!R1,-R2] ;((R1)-(R2))→R0
?、垡莆患拇嫫髌?/p>
?。跼n, ±Rm,LSL #《immede_5》{!}
[Rn, ±Rm,LSL #《immede_5》{!}
[Rn, ±Rm,ASR #《immede_5》{!}
[Rn, ±Rm,ROR #《immede_5》{!}
?。跼n, ±Rm,RPX]{!}
例:
LDR R0,[R1,R2,LSL #2] ;((R1)+(R2)*4→R0
?。?)后變址偏聽(tīng)偏信移尋址([Rn],偏移量)
Rn的值用作傳送數(shù)據(jù)的存儲(chǔ)器地址。在數(shù)據(jù)傳送后,偏移量加到Rn中,結(jié)果寫回到Rn。Rn不允許是R15。
該尋址方式又分為下列3種:
?、倭⒓磾?shù)偏移[Rn],#±《immde_12》
例:
LDR R0,[R1],#4 ;((R1))→R0,(R1)+4→R1
②寄存器偏移[Rn],±Rm
例:
LDR R0,[R3],-R8 ;((R3))→R0,(R3)-(R8)→R3
?、垡莆患拇嫫髌?/p>
?。跼n],±Rm,LSL#《immde_5》
?。跼n],±Rm,LSR#《immde_5》
?。跼n],±Rm,ASR#《immde_5》
[Rn],±Rm,ROR#《immde_5》
?。跼n],±Rm,RPX
例:
LDR R0,[R3],R8,LSL#2 ;((R3))→R0,(R3)+(R8)*4→R3
3 半字和有符號(hào)字節(jié)尋址方式
ARM中的半字和有符號(hào)字節(jié)取數(shù)和存數(shù)指令的尋址方式與字和無(wú)符號(hào)字節(jié)的尋址方式略有不同。
?。?)寄存器間接尋址([Rn])
例:
LDR R0,[R1]
STR R0,[R1]
?。?)前變址偏移尋址([Rn,偏聽(tīng)偏信移量]{!})
?。?)在數(shù)據(jù)傳送之前,將偏移量加到Rn不允許是R15。
該尋址方式又分為下列兩種:
①立即數(shù)偏移[Rn,#±《immed_8》]{!}
例:
LDR R0,[R5,#22]! ;((R5+22)→R0,(R5)+22→R5
?、诩拇嫫髌疲跼n,±Rm]{!}
例:
STRB R0,[R3,-R8] ;(R0)→(R3)-(R8),(R3)-(R8)→R3
?。?)后變址偏聽(tīng)偏信移尋址(Rn),偏移量)
Rn的值用作傳送數(shù)據(jù)的存儲(chǔ)器地址。在數(shù)據(jù)傳送后,偏移量加到Rn中,結(jié)果寫回到R n。Rn不允許是R15。
該尋址方式又分為下列3種:
?、倭⒓磾?shù)偏移[Rn],#±immed_8》
例:
LDR R0,[R3],-R8 ;((R5))→R0,(R5)+22→R5
②寄存器偏移[Rn],±Rm
例:
STR R0,[R3],-R8 ;(R0)→(R3),(R3)-(R8)→R3
4 塊尋址
ARM對(duì)堆棧的使用一般用多寄存器傳送指令,是一種有效的保存處理器狀態(tài)格多字節(jié)傳送的有效方式。ARM硬件中的堆棧分為以下4種:]
?、贊M向上生長(zhǎng)型:堆棧按高地址方向生長(zhǎng),當(dāng)前堆棧指針指向一個(gè)有效值;
?、诳障蛏仙L(zhǎng)型:堆棧按高地址方向生長(zhǎng),當(dāng)前堆棧指針指向一個(gè)空值;
?、蹪M向下生長(zhǎng)型:堆棧按低地址方向生長(zhǎng),當(dāng)前堆棧指針指向一個(gè)有效值;
?、芸障蛳律L(zhǎng)型:堆棧按低地址方向生長(zhǎng),當(dāng)前指針指向一個(gè)空值。
圖3-2說(shuō)明了4條帶不同變量和多字節(jié)傳送前后和內(nèi)存變化,以及基寄存器的變化情況。指令執(zhí)行前的基寄存器是R9,指令執(zhí)行后的基寄存器是R9’。
常見(jiàn)多字節(jié)傳送指令如表3-1所示。
表3-1內(nèi)FD|ED|FA|EA后綴只在堆棧時(shí)使用。F和E、分別代表指針指向?yàn)闈M或空。A和D分別表示堆棧是否向上或向下生長(zhǎng)。例如:堆棧如果是向上生長(zhǎng),STM指令向上存放,LDM指令向下讀取。IA、IB、DA、DB后綴在一般數(shù)據(jù)傳送時(shí)使用。注意:LDMED與LDMIB是同一條指令(下同)。
圖3-2多寄存器傳送示意
表3-1常見(jiàn)多字節(jié)傳送指令
?。?協(xié)處理器尋址方式
ARM協(xié)處理器尋址方式包括以下4種方式:
?。ǎ保┘拇嫫髦苯訉ぶ罚ǎ跼n]);
(2)前普址偏移尋址([Rn,#±《immed_8*4》]{!});
(3)后變址偏移尋址([Rn],#±《immed_8*4》);
?。ǎ矗?a target="_blank">參數(shù)無(wú)偏移尋址([Rn],{8-bit copro.Option}。
3.2.2 ARM指令的條件執(zhí)行
每條ARM指令都是有條件執(zhí)行,包括特權(quán)調(diào)用和協(xié)處理器指令,可根據(jù)執(zhí)行結(jié)果來(lái)選擇是否更新條件碼。若要更新條件碼,則指令中須包含后綴“S”。條件占32位指令的高4位。
一些指令(如CMP、CMN、TST、和TEQ不需要后綴“S”。它們唯一的功能就是更新條件標(biāo)志,且始終更新條件碼。更新之前保持不變。沒(méi)執(zhí)行的條件指令對(duì)標(biāo)志沒(méi)影響,一些指令只更新部分標(biāo)志,不影響其他標(biāo)志。
可以根據(jù)另外指令設(shè)置的標(biāo)志,有條件地執(zhí)行某條指令,分如下兩種情況:
l在更新標(biāo)志的指令后立即執(zhí)行;
l在插入的幾條不更新標(biāo)志的指令后執(zhí)行。
條件碼中的N、Z、C和V位的值將決定指令如何執(zhí)行。條件如表3-2所示。
表3-2 ARM條件碼
表3-2中符號(hào)“*”的說(shuō)明:HS、LO、HI、LS這4個(gè)條件碼指的是無(wú)符號(hào)數(shù),GE、LT、GT、LE這4個(gè)條件碼指的是符號(hào)數(shù)。
3.2.3 Load/Store類指令
1. 單字和無(wú)符號(hào)字節(jié)Load/Store類指令
功能:提供ARM寄存器和內(nèi)存之間單字節(jié)(8位)數(shù)據(jù)的傳送。
格式:
(1)零偏移(zero offet)
LDR|STR{《條件碼}}{B}{T} Rd,[Rn] ;((Rn))→Rd
零偏移指的是將Rn的內(nèi)容作為傳送數(shù)據(jù)的地址。
(2)前變址(pre-indexed offet)
LDR|STR{《條件碼》}{B} Rd,[Rn,《offset》]{!}
;((Rn)+offset)→Rd
;有“!”,(Rn)+offset→Rn
?。粺o(wú)“!”,Rn不變
前變址指的是在數(shù)據(jù)傳送之前,將偏移量加到Rn中,其結(jié)果作為傳送數(shù)據(jù)的存儲(chǔ)地址。若使用后綴“!”,則結(jié)果寫回到Rn中。Rn不允許是Rn15。
?。?) 程序相對(duì)偏移(program-relative)
LDR|STR{《條件碼》}Rd,Ladel ;(Label) →Rd
程序相對(duì)偏移指的是由PC計(jì)算偏移量,并將PC生成指令。不能使用后綴“!”?!埃蹋模摇d,Label”等價(jià)為“LDR Rd,[Rn],offset”等價(jià)為“((Rn))→Rd,(Rn)+offset→Rn]”
?。?) 后變址(post-indexed offset)
LDR|STR{《條件碼》{B}{T} Rd,[Rn],《offset》
后變址指的是將Rn的值用作傳送數(shù)據(jù)的存儲(chǔ)器地址,數(shù)據(jù)傳送后,偏移量加到Rn中,結(jié)果寫回到Rn。Rn不允許是R15?!癓DR Rd,[Rn],offset”等價(jià)為“((Rn))→,(Rn)+offset→Rn”。
其中:
B 可選后綴。若有B,則傳送Rd的最低有效字節(jié)。若操作碼是LDR,則將Rd的其他字節(jié)清零。
T 可選后綴。若有T,那么即使處理器在特權(quán)模式下,存儲(chǔ)系統(tǒng)也將訪問(wèn)看成是處理器在用戶模式下。T在用戶模式下無(wú)效,不能與前變址偏移一起使用T。
Rd ARM寄存器。
Rn 存儲(chǔ)器的基址寄存器,若指令是帶寫回(write back)的前變址(后綴為“!”)或后變址,或使用T后綴,則不允許Rn與Rd相同。
Offset Rn上的偏移量。
Label 程序相對(duì)偏移表達(dá)式,必須在當(dāng)前指令的前指令的±4KB內(nèi)。
! 可選后綴。若有“!”則將包含偏移量的地址寫回到Rn。若Rn是R15,則不能使用后綴“!”。
注釋:
?。?) offset 說(shuō)明
前變址和后變址格式中的offset可以是2種形式之一:
?。?) exression
其含義是符號(hào)表達(dá)式,通常是數(shù)字整數(shù)常量,取值在-4095~+4095之間。
?。?) ±Rm{.shift}
其中:
± 可選負(fù)號(hào)。若有符號(hào)“-”,則從Rn中減去偏移量。否則,將偏移量加到Rn中。
Rm 內(nèi)含偏移量的寄存器。Rm不允許是R15。
Shift Rm的可選移位方法??梢允茿SR、LSL、LSR、ROR、RRX的任何一種。詳細(xì)說(shuō)明見(jiàn)ARM數(shù)據(jù)處理類指令的第二操作數(shù)。
(4) 字地址對(duì)準(zhǔn)
大多數(shù)情況下,必須保證用于32位傳送的地址是32位對(duì)準(zhǔn)的。
若系統(tǒng)中有協(xié)處理器(CP15),則允許對(duì)準(zhǔn)檢查,若允許對(duì)準(zhǔn)檢查,則非字對(duì)準(zhǔn)的32位傳送會(huì)引起對(duì)準(zhǔn)異常。若系統(tǒng)中沒(méi)有系統(tǒng)協(xié)處理品(CP15),或禁止對(duì)準(zhǔn)檢查,則有:
對(duì)于STR,將指定的地址取成4的倍數(shù)。
對(duì)于LDR,則
l將指定的地址取成4的倍數(shù)。
l由結(jié)果地址讀取4個(gè)字節(jié)的數(shù)據(jù)。
l依據(jù)地址的位[1:0],將讀取的數(shù)據(jù)循環(huán)右移1、2或3個(gè)字節(jié)。
對(duì)于小端存儲(chǔ)系統(tǒng),這使尋址的字節(jié)占用寄存器的最低有效字節(jié)。
對(duì)于大端存儲(chǔ)系統(tǒng),這使尋址的字節(jié)占用:
-位[31:24],若地址的位[0]為0;
-位[15:8],若地址的位[0]為1。
?。?) 使用R15讀取
使用R15(程序計(jì)數(shù)器)讀取會(huì)引起處理器轉(zhuǎn)移到所讀取地址的指令。
對(duì)于讀取值的位[1:0],有:
l對(duì)于ARM體系結(jié)構(gòu)v3及以下版本,忽略位[1:0]。
l對(duì)于ARM體系結(jié)構(gòu)v4及以上版本的非T變量,位[1:0]為0。
l對(duì)于ARM體系結(jié)構(gòu)v5及以上版本的T變量,則有
-對(duì)于讀取到R15的值,其位[1:0]不允許是ob10;
-對(duì)于讀取到R15的值的位[0]置位,則處理器轉(zhuǎn)到Thumb狀態(tài)。
當(dāng)使用R15讀取時(shí),不能使用后綴“B”或“T”。
?。?) 使用R15存儲(chǔ)
通常應(yīng)盡量避免使用R15存儲(chǔ)。
若使用R15存儲(chǔ),則存儲(chǔ)的值是當(dāng)前指令的地址加上實(shí)現(xiàn)所定義的常量。對(duì)于特寫的處理器這個(gè)常量始終不變。
例 1:將R0中的內(nèi)容存放進(jìn)外設(shè)中。
LDR R1,UARTADD ;將UART地址放進(jìn)R1中
STRB R0,[R1] ;將數(shù)據(jù)放進(jìn)外設(shè)中
UARTADD & &1000000 ;UARTR的地址值
例 2:
LDR R8,[R10]! ;((R10))→R8
LDRNE R2,[R5,#960]! ;Z≠14時(shí)((R5)+960)→R2,(R5)+960→R5
STR R2,[R9,#consta-struc] ;consta-struc是常量的表達(dá)式,該常量的范圍為1~4095
STRB R0,[R3,-R8,ASR#2] ;R0→(R3-R8/4),存儲(chǔ)R0的最低有效字節(jié),R3和R8不變
STR R%,[R7],#-8 ;讀取一個(gè)字,該字位于標(biāo)號(hào)loacaldata所在地址
2. 半字和有符號(hào)字節(jié)Load/store類指令
功能:提供ARM寄存器和內(nèi)存之間半字(16位)和有符號(hào)字節(jié)(8位)數(shù)據(jù)的傳送。
格式:
?。?) 零偏移(zero offset)
LDR|STR{《條件碼》}H|SH|SB Rd,[Rn]
(2) 前變址(pre-indexed offset)
LDR|STR{《條件碼》}H|SH|SB Rd,[Rn,《offset》]{!}
?。?) 程序相對(duì)偏移(pregram-relatve)
LDR|STR{《條件碼》}H|SH|SB Rd,Label
?。?) 后變址(post-indexed offset)
LDR|STR{《條件碼》}H|SH|SB Rd,[Rn],《offset》
其中:
H|SH|SB 表示數(shù)據(jù)類型選擇。
SH 對(duì)有符號(hào)半字(僅LDR);
H 對(duì)無(wú)符號(hào)半字;
SB 對(duì)有符號(hào)字節(jié)(僅LDR)。
Label 程序相對(duì)偏移表達(dá)式。必須是在當(dāng)前指令的±255字節(jié)范圍內(nèi)。
Offset 加在Rn上的偏移量。含義見(jiàn)注釋。
Rn和“!”同前面第1條(LDR和STR字和無(wú)符號(hào)字節(jié))。
注釋:
?。?) offset說(shuō)明
前變址和后變址格式中的offset可以是下兩種形式之一:
?、賓xpression含義同前一條指令,取值在-255~+255范圍之間。
?、凇繰m含義同前一條指令。
(2) 半字傳送的地址對(duì)準(zhǔn)
半字傳送的地址必須是偶數(shù)。
若系統(tǒng)有系統(tǒng)協(xié)處理器(CP15),則可允許對(duì)準(zhǔn)檢查。若允許對(duì)準(zhǔn)檢查,則非對(duì)準(zhǔn)的16位傳送會(huì)引起對(duì)準(zhǔn)異常。若系統(tǒng)沒(méi)有系統(tǒng)協(xié)處理器(CP15)或禁止對(duì)準(zhǔn)檢查,則有
l非半字對(duì)準(zhǔn)的16位讀取將使Rd內(nèi)容不可靠;
l非半字對(duì)準(zhǔn)的16位存儲(chǔ)將使在address和(address-1)的2個(gè)字節(jié)不可靠。
(3) 不能將半字或字節(jié)讀取到R15。
例 1:
LDREQSH R11,[R6] ;(有條件地)R11←[R6],讀取16位半字,有符號(hào)擴(kuò)展到32位
LDH R1,[R0,#22] ;R1←[R0+22],讀取16位半字,零擴(kuò)展到32位
STR R4,[R0+R1] ;存儲(chǔ)最低的有效半字到R0+R1地址開始的兩個(gè)字節(jié),地址寫回到
;R0
LDRSB R6,constf ;讀取位于標(biāo)號(hào)constf地址中的字節(jié),有符號(hào)擴(kuò)展
例 2:
ADD R1,ARRAY1 ;ARRAY1 為半字?jǐn)?shù)組
ADR R2,ARRAY2 ;ARRAY2為字?jǐn)?shù)組
ADR R3 ENDARR1 ;ARRAY1+2
LOOP LDRSH R0,[R1],#2 ;取得有符號(hào)半字?jǐn)?shù),擴(kuò)展為字
STRR0,[R2],#4
CMP R1,R3
BLT LOOP
3. 雙字Load/Store類指令
功能:提供ARM寄存器和內(nèi)存之間雙字(64位)數(shù)據(jù)的傳送。
格式:
?。?) 零偏移(zero offset)
LDR|STR{《條件碼》}D Rd,[Rn]
?。?) 前變址格式(pre-indexed offset)
LDR|STR{條件碼》}D Rd,[Rn,《offset》]{!}
(3) 程序相對(duì)偏移(pregram-relatve)
LDR|STR{《條件碼》}D Rd,LABEL
(4) 后變地址格式(post-indexed offset)
LDR|STR{《條件碼式》}D Rd,[Rn],《offset》
其中:
Rd 讀取或指令寄存器其中的一個(gè),另一個(gè)是R(d+1).Rd必須是偶數(shù)寄存器,且不是R14.
Rn 除非指令為零移,或不帶寫回的前索引,否則R不允許是Rd和R(d+1)相同。
Offset 加在Rn上的偏移量。含義同3.2.3節(jié)第1條指令。
Label 程序相對(duì)偏移表達(dá)式.Label必須是在當(dāng)前指令的±255字節(jié)范圍內(nèi)。
??! 可選后綴。若有”!”,則包含偏移量的最后地址寫回到Rn.
注釋:
對(duì)于雙字節(jié)傳送,地址必須是8的倍數(shù)。若系統(tǒng)有系統(tǒng)協(xié)處理器,可允許對(duì)準(zhǔn)檢查。若允許對(duì)準(zhǔn)檢查,慢非雙字準(zhǔn)的64位傳送將引起對(duì)準(zhǔn)異常。該指令適用于ARMv5TE指令系統(tǒng)及以上版本。
例:
LDARD R6,[R11] ;((R11)→R6,((R11)+4)→R7
STRD R4,[R9,#24] ;(R4)→(R9)+24,(R5)→(R9)+24
4. 多寄存器Load/Store類指令
功能:讀取和存儲(chǔ)多個(gè)寄存器,可以傳送R0~R15的任何組合。
格式:
(1) 標(biāo)準(zhǔn)格式
LDR|STM{《條件碼》}《mode》Rn{!}《寄存器》
(2) 非用戶模式下,用下面可以同時(shí)把當(dāng)前的SPSR寫入CPSR中,轉(zhuǎn)向用戶模式,寄存器組飲包含PC.
LDM{《條件碼》}《mode》Rn{!},《寄存器組+PC》^
(3) 非用戶模式下,用下面格式可以實(shí)現(xiàn)訪問(wèn)用戶模式的寄存器,但寄存器組不包含PC.
LDM|STM{《條件碼》}《mode》Rn,《寄存器組-PC》^
其中:
mode IA、IB、DA、DB、FD、ED、FA、EA之一。
Rn 基址寄存器,裝有傳送數(shù)據(jù)的初始地址。Rn是不允許是R15。
??! 可選后綴。若有“!”,則結(jié)果地址寫回到Rn。
Reglist讀取或存儲(chǔ)的寄存器列表,包含在括號(hào)中,它也可包含寄存器的范圍。若包含多于1個(gè)寄存器列表或包含寄存器范圍,則必須用逗號(hào)分開。
^ 可選后綴,不允許用戶模式或系統(tǒng)模式下使用。它有兩個(gè)目的:
l操作碼是LDM且reglist中飽包含PC(R15),那么出除了正常的多寄存器傳送外,將SPSR也拷貝到CPSR中。這用于從異常處理返回,僅在異常模式下使用。
l數(shù)據(jù)傳入或傳出的是用戶模式的寄存器,而不是當(dāng)前模式的寄存器。
注意:對(duì)于LDM指令,如包含PC,位0=1時(shí),轉(zhuǎn)至Thumb狀態(tài)。寄存器組中一般不應(yīng)有Rn,它至少有1個(gè)寄存器。FD、ED、FA、DA用于堆棧操作;IA、IB、DA、DB用于一般的數(shù)據(jù)傳送。
注釋:
?。ǎ保┓亲謱?duì)準(zhǔn)地址
這些指令忽略地址的位[1:0]。在帶有系統(tǒng)協(xié)處理器的系統(tǒng)中,若對(duì)準(zhǔn)檢查使能,則這2位的非零值將引起對(duì)準(zhǔn)異常。
(2)讀取到R15
到R15(程序計(jì)數(shù)器)的讀取將引起處理器轉(zhuǎn)移到讀取地址處的指令。在ARM體系結(jié)構(gòu)v5及以上版本的T變量中若讀取的位[0]置位,則到R15的讀取將導(dǎo)致處理器切換到執(zhí)行Thumb指令。
(3)帶寫回的存/取基址寄存器
如果Rn包含在寄存器列表中,且用后綴“!”,指明要寫回(write back),那么:
l若操作碼是STM,縣城Rn是寄存器列表中數(shù)字最小的寄存器,則將初值保存。
lRn的讀取和儲(chǔ)存值不可預(yù)知。
例1:若保存3個(gè)工作寄存器狀態(tài)和返回地址:
STMFD R13!,{R0-R2,R14}
若恢復(fù)3個(gè)工作寄存器狀態(tài)和返回地址:
LDMFD R13!,{R0-R2,R14}
例2:
LDMFD R8,{R0,R2,R9} ;((R8))→R0
??;((R8)+4)→R2
;((R8)+8)→R9
STMDB R1!,{R3-R6,R11,R12} ;(R3)→R1-4
;(R4)→R1-8
;(R5)→R1-12
?。唬≧6)→R1-16
??;(R11)→R1-20
;(R12)-24→R1
STMD R13!,{R0,R4-R7,LR} ;寄存器進(jìn)棧
例3:子程序調(diào)用
SUMB1 STMFD SP!,{R0-R2,R14} ;保護(hù)R0~R2和返回地址
…… ;其它指令
BL ;允許子程序嵌套
…… ;其它指令
LDMFD SP!,{R0-R2,R15} ;恢復(fù)R0~R2,返回子程序調(diào)用程序后執(zhí)行
5. 預(yù)讀取PLD指令
功能:cache預(yù)讀取(PLD,PreLoad),使用PLD指示存儲(chǔ)系統(tǒng)從后面幾條指令所指定的存儲(chǔ)器地址讀取,存儲(chǔ)系統(tǒng)可使用這種方法加速以后的存儲(chǔ)器訪問(wèn)。
格式:
PLD[Rn,{offset}]
其中:
Rn 存儲(chǔ)器的基址寄存器。
Offset 加在Rn上的偏移量。含義同3。2。3節(jié)第1條指令。
注釋:
PLD指令適用于ARM v5TE指令及以上版本。
例:
PLD [R9,#-2481]
PLD [R0,#av*4] ;av*4必須在匯編時(shí)求值,范圍為-4095~4095內(nèi)的整數(shù)
PLD [R5,r8,Lsl#2]
6. 內(nèi)存和寄存器交換類指令
功能:用一條指令實(shí)現(xiàn)在寄存器和存儲(chǔ)器之間交換數(shù)據(jù)。
格式:
SWP{《條件碼》}{B} Rd,Rm,[Rn] ;((Rn))→Rd,Rm→Rn
;n≠m,d
其中:
B 可選后綴。若有B,則交換字節(jié);否則,交換32位字。
Rd ARM寄存器。數(shù)據(jù)從存儲(chǔ)器讀取到Rd。
Rm ARM寄存器。Rm的數(shù)據(jù)存儲(chǔ)到存儲(chǔ)器。Rm可以與Rd相同。Rn必須與Rd和Rm不同。
注釋:
對(duì)非字對(duì)準(zhǔn)地址的處理同LDR和STR指令。
例:
ADR R0,SEMAPHORE
SWPB R1,R1,[R0] ;交換字節(jié)
3.2.4 ARM數(shù)據(jù)處理類指令
大多數(shù)ARM通用數(shù)據(jù)處理有一個(gè)靈活的第2操作數(shù)(flexi second operand)。在每一個(gè)指令的格式中以“operand2”表示。
第2條操作數(shù)有如下2種可能的格式:
(1)#immed_8r
常量的表達(dá)式。常量必須對(duì)應(yīng)于8位位圖(pattern0。該位圖在32位字中,被循環(huán)移位偶數(shù)位(0,2,4,8,…,26,28,30)。合法常量:0xFF、0xFF000、0xF0000000F。非法常量:0x101、0xFF04、0xFF003、0xFFFFFFFF。
?。?)±Rm {,shift}
Rm 存儲(chǔ)第2操作數(shù)ARM寄存器??捎酶鞣N方法對(duì)寄存器中的位圖進(jìn)行移位或循環(huán)移位。在指令操作的結(jié)果用作第2操作數(shù),但Rm本身不變。
Shift Rm的移位方法,可以是下面的任何一種:
ASR n 算術(shù)右移n位(1≤n≤32)。
LSL n 邏輯左移n位(0≤n≤31)。
LSR n 邏輯右移n位(1≤n≤32)。
ROR n 循環(huán)右移n位(0≤n≤32)。
RRX 帶進(jìn)位的循環(huán)右移1位。
Type Rs 其中:Type ASR、LSR、ROP中的種;
Rs 提供移位量的ARM寄存器,僅使用于最低有效字節(jié)。
ASR、LSL、LSR、ROP和RRX的詳細(xì)說(shuō)明如下:
?、?ASR
若將Rm中的內(nèi)容看作是有符號(hào)的補(bǔ)碼整數(shù),那么算術(shù)右移(ASR,Arithmetic Shift Right)n位,即Rm中的內(nèi)容除以 。將原來(lái)的位拷貝到寄存器左邊的n位中(即空出的最高補(bǔ)符號(hào)位),見(jiàn)圖3-3(a)。
?、?LSR和LSL
若將Rm中內(nèi)容看作是無(wú)符號(hào)整數(shù),則邏輯右移(LSR,Logical Shift Right)n位,即Rm中的內(nèi)容除以 ,寄存器左邊的n位置0,見(jiàn)圖3-3(b)。
若將Rm中內(nèi)容看作是無(wú)符號(hào)整數(shù),則將邏輯左移(LSR,Logical Shift Left)n位,即Rm四的內(nèi)容乘以 ,可能會(huì)出現(xiàn)溢出且無(wú)警告,寄存器右邊的n 位置0,見(jiàn)圖3-3(b)。
?、?ROR
循環(huán)右移(ROR,Rotate Right)n位,把寄存器內(nèi)容循環(huán)右移,見(jiàn)圖3-3(c)。
?、?RRX
若將Rm中內(nèi)容看作是無(wú)符號(hào)整數(shù),則帶進(jìn)位右環(huán)移n位,寄存器左邊的n位置0,見(jiàn)圖3-3(d)。
圖3-3移位操作過(guò)程
1 數(shù)據(jù)運(yùn)算類指令
功能:完成數(shù)據(jù)在寄存器中的運(yùn)算,這些運(yùn)算包括32位數(shù)據(jù)的算術(shù)、位操作,其中某一個(gè)操作數(shù)可以經(jīng)過(guò)移位或循環(huán)運(yùn)算。
格式:
《操作碼》{《條件碼》}{S}Rd,Rn,Operand2
操作碼 包括ADD、SUB、RSB、ADC、SBC、RSC、AND、ORR、EOR、BIC、MOV、MVN、CMP、CMN、TST和TEQ指令。
其中:
S 可選后綴。若指定S,則根據(jù)操作結(jié)果更新條件標(biāo)志(N、Z、C和V)。
Rd ARM結(jié)果寄存器。
Rn 存儲(chǔ)第1操作數(shù)的ARM寄存器。
Operand 第2操作數(shù)。詳細(xì)說(shuō)明請(qǐng)見(jiàn)3.2.4節(jié)第2操作數(shù)說(shuō)明。
ARM的數(shù)據(jù)運(yùn)算類指令用法如表3-3所示。
表3-3 ARM運(yùn)算類指令
注釋:
?。?) 條件碼標(biāo)志
若指定S,那么ADD、SUB、RSB、ADC、SBC、RSC指令根據(jù)結(jié)果更新標(biāo)志N、Z、C和V。CMP、CMN、TST和TEQ指令不需S。注意:減法(含比較)夠減時(shí),C=1。而AND、OPR、EOP、BIC、MOV和MVN指令將:①根據(jù)結(jié)果更新標(biāo)志N和Z;②計(jì)算Operand2時(shí)更新標(biāo)志C;③不影響V標(biāo)志。
(2) R15的使用
ADD、SUB、RSB、ADC、SBC、RSC、AND、ORR、EOR、BIC、MOV和MVN指令將R15作為Rn使用,那么使用的值是指令的地址加8。
若將用R15作為Rd,則
l執(zhí)行轉(zhuǎn)移到結(jié)果對(duì)應(yīng)的地址。
l若后綴“S”,則將當(dāng)前模式的SPSR拷貝到CPSR??梢允褂眠@點(diǎn)從異常返回。
在有寄存器控制移位的任何數(shù)據(jù)處理指令中,不能將R15作為Rd或任何操作數(shù)來(lái)使用。
CMP、CMN、TST和TEQ指令若將R15用作Rn,則使用的值是指令的地址加8。在有寄存器控制移位的任何數(shù)據(jù)處理指令中,不能將R15用于任何操作數(shù)。
例1:
ADD R2,R1,R3 ;(R1)+(R3)→R2
例2:
SUBS R2,R2,#1 ;(R2)-1→R2
BEQ LABEL ;如等于0,轉(zhuǎn)向LABEL
例3:R0中的內(nèi)容乘以5:
ADD R0,R0,R0,LSL #2 ;(R0)*5→R0
ADD R0,R0,LSL #1
例4:R0中的內(nèi)容乘以10:
ADD R0,R0,R0,LSL #2 ;(R0)*10→R0
MOV R0,R0,LSL #1
例5:R0中的內(nèi)容乘以10,再加R1中的內(nèi)容:
ADD R0,R0,R0,LSL #2 ;(R0)*10+R1→R0
MOV R0,R1,R0,LSL #1
例6:
ADDS R2,R2,R0 ;(R3R2)+(R1R0)→R3R2
ADC R3,R3,R1
例7:
ADDNE R0,R1,#&ff ;if Z=0 then(R1)+0xff→R0
例8:R1中的內(nèi)容乘7,送給R0:
RSB R0,R1,R1,LSL #3 ;(R1)*7→R0
2 前導(dǎo)零計(jì)數(shù)指令
功能:CLZ(Count Leading Zeros)指令對(duì)Rm中值的高位(leading zeros)個(gè)數(shù)進(jìn)行計(jì)數(shù),結(jié)果放到Rd中。若源寄存器全為0,則結(jié)果為32。若[31]為1,則結(jié)果為0。
格式:
CLZ{《條件碼》}Rd,Rm
其中:
Rd ARM結(jié)果寄存器,Rd不允許是R15。
Rm 操作數(shù)寄存器。
注釋:
CLZ指令適用于ARM v5指令系統(tǒng)以上版本。這條指令不影響條件碼標(biāo)志。
例:
CLZ R4,R9
CLZNE R2,R3
3 乘法指令
格式:
(1) MUL{《條件碼》}{S},Rd,Rm,Rs
(2) MLA{《條件碼》}Rd,Rm,Rs,Rn
其中:
Rd 結(jié)果寄存器。
Rm,Rs,Rn 操作數(shù)寄存器。
R15不能用于Rd,Rm,Rs或Rn。Rd不能與Rm相同。
?。?) 《mul》{《條件碼》}{S}RdHi,RdLO,Rm,Rs
mul中類型包括UMILL、UMLAL、SMULL、SMLAL。
其中:
RdLo,RdHi ARM結(jié)果寄存器。對(duì)于UMLAL和SMLAL,這兩個(gè)寄存器用于保存累加值。
Rm,Rs 操作數(shù)寄存器。
R15不能于RdHi,RdLo,Rm或Rs。RdLO、RdHi和Rm必須是不同的寄存器。
?。?) SUML《x》《y》{條件碼}Rd,Rm,Rs
其中:
《x》 B或T。B意味著使用Rm的低端(位[15:0]),T意味著使用Rs的高端(位[31:16])。
《y》 B或T。B意味著使用Rm的低端(位[15:0]),T意味著使用Rs的高端(位[31:16])。
Rd 結(jié)果寄存器。
Rm,Rs 乘數(shù)寄存器。
R15不能用于Rd,Rm和Rs。Rd、Rm、Rs可用相同的寄存器。
(5) SMLA《x》《y》{條件碼}Rd,Rm,Rs可用相同的寄存器。
其中:
《x》、《y》、Rm和Rn含義同SMUL《x》《y》指令。
R15不能用于Rd、Rm和Rs。Rd、Rm、Rs可用相同的寄存器。
(6) SMULW《y》{條件碼}Rd,Rm,Rs
其中:
《y》、Rd、Rm、Rs和Rn含義同SMUL《x》《y》指令。
R15不能用于Rd、Rm和Rs。Rd、Rm、Rs可用相同的寄存器。
?。?) SMULW《y》{條件碼}Rd,Rm,Rs
其中:
《y》、Rd、Rm、Rs和Rn含義同SMUL《x》《y》指令。
R15不能用作Rd、Rm、Rs或Rn的任何一個(gè)。任何Rd、Rm、Rs或Rn可用相同的寄存器。
?。?) SMULW《y》{條件碼}Rd,Rm,Rs,Rn
其中:
《y》、Rd、Rm、Rs和Rn含義同SMUL《x》《y》指令。
R15不能用作Rd、Rm、Rs或Rn的任何一個(gè)。任何Rd、Rm、Rs或Rn可用相同的寄存器。
?。?) SMULW《y》{條件碼}RdLo,RdHi,Rm,Rs
其中:
《x》《y》含義同SMULxy指令。
RdHi,RdLo 結(jié)果寄存器。它們也存儲(chǔ)累加值。
Rm,Rs 乘數(shù)寄存器。
ARM乘法類指令用法如表3-4所示。
表3-4 ARM乘法類指令
注釋:
若指定S標(biāo)志位,則MUL和MLA指令將:①根據(jù)結(jié)果更新標(biāo)志N和Z;②不影響標(biāo)志V;③在ARM v4以前版本中標(biāo)志C不可靠;④在ARM v5及以后版本中不影響標(biāo)志C。
若指定結(jié)果S標(biāo)志位,則UMULL,UMLAL,SMULL和SMLAL指令將:①根據(jù)結(jié)果更新標(biāo)志N和Z;②在ARM v4及以前版本中標(biāo)志C不可靠;③在ARM v5及以后版本中不影響標(biāo)志C或V。
SMULAxy指令不影響任何條件碼標(biāo)志。若加法出現(xiàn)溢出,則置位標(biāo)志Q。使用MRS指令讀標(biāo)志Q的狀態(tài)。注意:這條指令永遠(yuǎn)也不會(huì)清除Q標(biāo)志。要清除Q標(biāo)志,則應(yīng)使用MSR指令。
SMULxy、SMULWy、SMLALxy指令不影響任何條件標(biāo)志。
SMULxy、SMULWy、SMLALxy、SMLAxy和SMLAWy指令適用于ARM v5TE指令系統(tǒng)及以上版本。
例:
SMLALLES R8,R9,R7,R6
SMULLNE R0,R1,R9,R0
4 QADD、QSUB、QDAAA和QDSUB指令
功能:這4條指令屬于DSP增強(qiáng)指令,完成飽和加、飽和減,飽和乘2加、飽和乘2減4種飽和運(yùn)算功能。
格式:
《操作碼》{條件碼}Rd,Rm,Rn
《操作碼》包括:QADD、QSUB、QDADD和QDSUB指令。
其中:
Rd 結(jié)果寄存器。
Rm,Rn 操作寄存器。
注釋:
飽和運(yùn)算是DSP指令所特有的功能,對(duì)加/減法指令的結(jié)果做了如下修改:
(1) 如果加/減法指令的結(jié)果在- ~ -1之間,飽和運(yùn)算的結(jié)果取加/減法指令的結(jié)果。
?。?) 如果加/減法指令的結(jié)果大于 -1,飽和運(yùn)算的結(jié)果取最終結(jié)果為 -1。
?。?) 如果加/減法指令結(jié)果小于- ,飽和運(yùn)算的結(jié)果取最終結(jié)果為時(shí)尚- 。
QDADD和QDSUB指令計(jì)算SAT(Rm+SAT(Rn*2)),飽和可發(fā)生在加倍操作,加法上,或兩咱情況下同時(shí)發(fā)生。或飽和僅發(fā)生在加倍操作上,則標(biāo)志Q置位,但最后結(jié)果是不飽和的。SAT意為飽和運(yùn)算。
這些指令不影響標(biāo)志N、Z、C和V。若出現(xiàn)飽和,則置位Q標(biāo)志。可使用MRS指令來(lái)讀Q標(biāo)志的狀態(tài)。注意:即使是飽和不出現(xiàn),這些指令也從不清除Q標(biāo)志。使用MSR指令清除Q標(biāo)志。
QADD、QSUB、QDADD和QDSUB指令適用于ARM v5TE指令系統(tǒng)及以上版本。
例:
QADD R0,R1,R9 ;SAT(R1+R9)→R0
QDSUBLT R9,R0,R1 ;SAT(R0-SAT((R9)*2))→R9
3.2.5 ARM轉(zhuǎn)移類指令
ARM轉(zhuǎn)移類指令完成循環(huán)、調(diào)用子程序和從ARM狀態(tài)轉(zhuǎn)向Thumb狀態(tài)等功能,包括B、BL、BX和BLX指令。
1 轉(zhuǎn)移/轉(zhuǎn)移帶鏈接類指令
功能:B、BL指令完成當(dāng)前執(zhí)行指令地址的轉(zhuǎn)移,偏移地址量可以達(dá)到32M,BL指令可以把轉(zhuǎn)移指令后第1條指令的地址放進(jìn)鏈接寄存器R14中完成連接作用,通常用來(lái)完成子程序的調(diào)用。
轉(zhuǎn)移地址通常由24位有符號(hào)數(shù)組成,由于指令地址的代位為00,故可進(jìn)行2位的左移運(yùn)算,因此總的偏移量達(dá)到±32M。
格式:
B{L}{《條件碼》}《Label》
其中:
Label 程序相對(duì)偏移表達(dá)式。
注釋:
BL(Branch and Link)指令將下一條指令的地址拷貝到R14(LR,鏈接寄存器)并引起處理器轉(zhuǎn)移到Label。BL指令(L=1),等價(jià)于先把(PC)→R14,再(PC)+offset→PC.
機(jī)器級(jí)的B和BL指令限制在當(dāng)前指令的± (±32M)字節(jié)范圍內(nèi)。但是,即使Label走超出了該范圍,匯編可以使用這些指令。
例1:條件轉(zhuǎn)移。
CMP R0,35 ;如果R0小于5
BLT SUB1 ;則轉(zhuǎn)SUB1
BGE SUB2 ;否則轉(zhuǎn)SUB2
例2:程序調(diào)用。
BL SUB ;調(diào)用子程序SUB
… ;返回點(diǎn)
SUB … ;子程序入口
MOV PC,R14 ;執(zhí)行完返回
例3:執(zhí)行循環(huán)。
MOV R0,#10 ;設(shè)置循環(huán)次數(shù)
LOOP …
SUBS R0,#1 ;循環(huán)次數(shù)減1
BNE LOOP ;如果循環(huán)次數(shù)不為0,繼續(xù)循環(huán)
… ;否則結(jié)束循環(huán)
2 轉(zhuǎn)移交換、轉(zhuǎn)移帶鏈接和交換指令BX,BLX
功能:BX、BLX指令用來(lái)支持者Thumb指令集,可以全處理器由ARM指令轉(zhuǎn)向Thumb指令或者由于某種原因Thumb指令返回到執(zhí)行ARM指令。
格式:
?。ǎ保〣{L}X{《條件碼》}寄存器Rm
?。ǎ玻〣LX《Label》
其中:
RM 含有轉(zhuǎn)移地址的寄存器。Rm的位[0]不用來(lái)作為地址的一部分。若Rm的位[0]為1,則指令將CPSR中的標(biāo)志T置位,且將目標(biāo)地址的代碼解釋為Thumb代碼。若Rm的位[0]為0,則位[1]就不能為1。
注釋:
在指令格式中,寄存器Rm中可以存放轉(zhuǎn)移地址的值,如果Rm中的第0位為1,處理器將Thumb指令;如果為0,執(zhí)行ARM指令。
在指令格式2中偏移地址量的計(jì)算與B或BL指令相同。
BLX指令有如下用法:
l將下一條指令的地址拷貝到R14中(LR,鏈接寄存器)。
l轉(zhuǎn)移到Label或Rm中的地址。
l若下面的兩條中的任何一條成立,則指令集切換到Thumb,即
-Rm的位[0]為1;
-使用“BLX Label“形式。
機(jī)器級(jí)的“BLX Label“指令不能轉(zhuǎn)移當(dāng)前指令±32MB范圍之外的地址BLX指令格式1可以是條件或者無(wú)條件執(zhí)行,而指令格式2是無(wú)條件執(zhí)行。
例1:無(wú)條件轉(zhuǎn)移。
BX R0 ;按R0內(nèi)容轉(zhuǎn)移
??;如果R[0]為1,轉(zhuǎn)Thumb狀態(tài)
例2:Thumb子程序調(diào)用。
CODE32 ;ARM代碼
…
BLX TSUB ;Thumb代碼執(zhí)行
TSUB … ;Thumb指令TSUB子程序
BX R14 ;返回ARM代碼
3.2.6 ARM協(xié)處理器類指令
ARM協(xié)處理器指令完成與協(xié)處理器有關(guān)的操作,如協(xié)處理器內(nèi)部寄存器之間的數(shù)據(jù)傳送、協(xié)處理器與存儲(chǔ)器之間的數(shù)據(jù)傳送、協(xié)處理器與CPU寄存器之間的數(shù)據(jù)傳送。這些指令依賴于使用特寫的協(xié)處理器。協(xié)處理器設(shè)計(jì)者可以自由地按需要設(shè)計(jì)處理器的功能,而且這些指令通常借助于匯編器。
1CDP和CDP2指令(CDP,Coprocessor Data operation)
功能:完成協(xié)處理器寄存器數(shù)據(jù)操作。
格式:CDP{條件碼} CP#,opcodel,CRd,CRn,CRm{,opcode2}
CDP2 CP#,opcodel,CRd,CRn,CRm{,opcode2}
其中:
CP# 指令操作的協(xié)處理器名。標(biāo)準(zhǔn)名為pn,n為0~15范圍內(nèi)的整數(shù)。
Opcode1 協(xié)處理器的特定操作碼。
CRzn,CRm,CRn 協(xié)處理器寄存器。
Opcode2 可選的協(xié)處理器特定操作碼。
注釋:
CDP2指令設(shè)置條件碼為0b1111,為協(xié)處理器設(shè)計(jì)者提供額外的opcode空間。CDP2指的是適用于ARM v5指令系統(tǒng)及以上版本。
例:
CDP p1,10,C1,C2,C3 ;協(xié)處理器1中的處理器C2和C3完成操作10然后
?。粚⒔Y(jié)果放在C1中
CDPEQ p2,5,C1,C2,C3 ;如果Z位置1,那么協(xié)處理器2中的C2和C3完成
??;操作5(子操作2),然后將結(jié)果放在C1中
2 LDC和STC指令
功能:在存儲(chǔ)器和協(xié)處理器之間傳送數(shù)據(jù)。
格式:
?。?) 零偏移格式
LDC|STC{《條件碼》}{L}《CP#》,CRd,[Rn]
(2) 前變址格式
LDC|STC{《條件碼》}{L}《CP#》,CRd,[Rn,#offset]{!}
LDC2|STC2{《 CP#》》},CRd, [Rn,#offset]{!}
(3) 后變址格式
LDC|STC{《條件碼》}{L}《CP#》,CRd,[Rn],#offset
LDC2|STC2{《 CP#》》},CRd, [Rn],#offset
其中:
L 可選后綴,指明是長(zhǎng)整數(shù)傳送。
CP# 指令操作的協(xié)處理器名。標(biāo)準(zhǔn)名為pn,其中n為0~15范圍內(nèi)的整數(shù)。
CPd 用于讀取或存儲(chǔ)的協(xié)處理器寄存器。
Rn 存儲(chǔ)器基址寄存器。若指定R15,則使用的值是當(dāng)前指令地址加8。
Offset 偏移量,其值必須為4的整倍數(shù),范圍在0~1020之間。
注釋:
LDC2和STCC2指令設(shè)置條件碼條件碼為b1111,為協(xié)處理器設(shè)計(jì)者提供額外的opcode空間。LDC2和STC2指令適用于ARM v5指令系統(tǒng)及以上版本。注意:LDC2和STC2始終是無(wú)條件的。
例1:
LDC p6,CR1,[R4] ;將存儲(chǔ)器中的內(nèi)容取至協(xié)處理器6
??;寄存器CR1中R4為所以內(nèi)容地址
例2:
LDC p6,CR4,[R2,4] ;將存儲(chǔ)器中的內(nèi)容取至協(xié)處理器6
;寄存器CR4中R2+4為所以內(nèi)容地址
例3:
STC p8,CR8,[R2,#4]! ;將協(xié)處理器8寄存器CR8中的內(nèi)容存
?。恢链鎯?chǔ)器中R2+4為所存內(nèi)容的地址
?。蝗缓?,R2=R2+4
例4:
STC p6,CR9,[R2],#-16 ;將協(xié)處理器6寄存器CR9中的內(nèi)容存
?。恢链鎯?chǔ)器中R2為所存內(nèi)容的地址
??;然后,R2=R2-16
3 MRC、MRC2、MCR和MCR2指令
功能:在協(xié)處理器與ARM寄存器之間傳送數(shù)據(jù)。
格式:
?。ǎ保膮f(xié)處理器傳送至ARM寄存器
MRC{《條件碼》}《CP#》,《Opcode1》,Rd,CRn,CRm{,《Opcode2》}
MRC2 《CP#》,《Opcode1》,Rd,CRn,CRm{,《Opcode2》}
?。ǎ玻腁RM寄存器傳送至協(xié)處理器
MCR{《條件碼》}《CP#》,《Opcode1》,Rd,CRn,CRm{,《Opcode2》}
MRC2 《CP#》,《Opcode1》,Rd,CRn,CRm{,《Opcode2》}
本組指令格式中所有操作數(shù)的含義同(CDP和CDP2)。
注釋:
MRC2和MCR2指令設(shè)置條件碼為0b1111,為協(xié)處理器設(shè)計(jì)者提供額外的操作碼字段。MRC2和MCR2指令適用于ARM v5指令系統(tǒng)及以上版本。注意:MRC2和MCR2始終是無(wú)條件的。
例1:
MRC p15,R4,C0,C2,3 ;協(xié)處理器15中的寄存器C0和C2完成
??;操作5(子操作3),然后將結(jié)果傳到
??;CPU寄存器4中
例2:
MCR p14,1,R7,C7,C12,6 ;協(xié)處理器14在CPU寄存器7中完成
??;操作1(子操作6,然后將結(jié)果傳到協(xié)
;處理器14的寄存器C12中
4 MCRR和MRRC指令
功能:在2個(gè)ARM寄存器和協(xié)處理器之間進(jìn)行數(shù)據(jù)傳送。
格式:
MRRC{《條件碼》}《CP#》,《Opcode1》,Rd,CRn,CRm
MCRR{《條件碼》}《CP#》,《Opcode1》,Rd,CRn,CRm
本指令格式中所有操作數(shù)的含義同本小節(jié)第1條指令(CDP和CDP·)。MCRR和MRRC指令適用于ARM v5TE指令系統(tǒng)及以上版本。
3.2.7 ARM雜項(xiàng)指令
1 狀態(tài)寄存器傳送至通用寄存器類指令
功能:將狀態(tài)寄存器的內(nèi)容傳送至通用寄存器。
格式:
MRS{《條件碼》}Rd,CPSR}SPSR
其中:
Rd 目標(biāo)寄存器,Rd不允許R15。
R=0 將CPSR中的內(nèi)容傳送目的寄存器。
R=1 將SPSR中的內(nèi)容傳送至目的寄存器。
注釋:
MRS與MSR配合使用,作為更新PSR的讀-修改-寫序列的一部分。例如:改變處理器或清除標(biāo)志Q。注意:當(dāng)處理器在用戶模式或系統(tǒng)模式下,一定不能試圖訪問(wèn)SPSR
這條指令不影響條件碼標(biāo)志。
例:
MRS R0,CRSR ;將CPSR中的內(nèi)容傳送至R0
MRS R3,SPSR ;將SPSR中的內(nèi)容傳送至R3
2 通用寄存器傳送至狀態(tài)寄存器傳送指令
功能:將通用寄存器的內(nèi)容傳送至狀態(tài)寄存器。
格式:
MSR{《條件碼》CPSR_f|SPSR_f,《#ommed_8r》
MSR{《條件碼》CPSR_《field》|SPSR_《field》,Rm
其中:
《field》字段可以是以下之一或多種:
lC:控制域屏蔽字段(PSR中的第0位到第7位);
lX:擴(kuò)展域屏蔽字段(PSR中的第8位到第15位);
lS:狀態(tài)域屏蔽字段(PSR中的第16位到第32位);
lF:標(biāo)志域屏蔽字段(PSR中的第24位到第31位)。
immed_8r 值數(shù)字常量的表達(dá)式。常量必須對(duì)應(yīng)8位位圖。該位圖在32位字中循環(huán)移位偶數(shù)數(shù)位。
Rm 源寄存器。
注釋:
同前一條指令(MRS)。
例1:設(shè)置N、Z、C、V標(biāo)志。
MSR CPSR_f,#&f0000000 ;僅高位有效,其他必須為0
例2:
僅置位C標(biāo)志,保留N、Z、V標(biāo)志。
MRS R0,CPSR ;將CPSR中的內(nèi)容傳送至R0
ORR R0,R0,#&1f ;置位R0的第29位
MSR CPSR_c,R0 ;再將R0中的內(nèi)容傳送至CPSR
3 軟件中斷指令SWI
格式:
SWI{《條件碼》immed_24
其中:
immed_24 表達(dá)式,其值范圍為0~ -1的整數(shù)(24位整數(shù))。
注釋:
?。?) SWI指令用來(lái)執(zhí)行系統(tǒng)調(diào)用,處理器進(jìn)入管理模式,并從地址0x08開始執(zhí)行指令《24位立即數(shù)》并不影響指令的執(zhí)行,由系統(tǒng)所解釋。CPSR保存到管理模式的SPSR中執(zhí)行轉(zhuǎn)移到SWI向量。
?。?) 條件碼標(biāo)志。這條指令不影響條件碼標(biāo)志。
例1:輸出字符“A”
MOV R0,#“A” ;從R0中得到“A”
SWI SWI_WriteC ;然后顯示
例2:通過(guò)SWI指令輸出字符串
…
BL STROUT ;輸出如下信息
= “Hello World”,&0a,&0d,0
… ;返回
STROUT LDRB R0,R[14],#1 ;得到字符
CMP R0,#0 ;檢查結(jié)束標(biāo)記
SWINE SWI_WriteC ;如果沒(méi)有結(jié)束,則繼續(xù)
BNE STROUT ;…循環(huán)
ADD R14,#3 ;字對(duì)齊
BIC R14,#3
MOV PC,R14 ;返回
例3:結(jié)束用戶程序返回監(jiān)控程序
SWI SWI _Exit ;返回
4 斷占指令(v5T)
格式:
BKPT immmed_16
其中:
immmed_16 表達(dá)式,基值范圍為0~65536內(nèi)的整數(shù)(16位整數(shù))。
注釋:
支持軟件調(diào)試,執(zhí)行時(shí)中斷正常指令,進(jìn)入相應(yīng)的調(diào)試子程序。BKPT指令適用于ARM v5指令系統(tǒng)及以上版本。
例:
BKPT
3.3 Thumb指令系統(tǒng)
并非所有的ARM處理器都可以執(zhí)行Thumb指令,在指令集名中,含有T的均可執(zhí)行Thumb指令,如ARM7TDMI。
CPSR中的T標(biāo)志決定是執(zhí)行Thumb指令還是ARM指令,如置位,執(zhí)行Thumb指令,否則執(zhí)行ARM指令。
ARM在復(fù)位以后,執(zhí)行ARM指令。通常至Thumb指令的執(zhí)行是由一條轉(zhuǎn)移和交換指令完成的,如BX指令。但是例程處理程序中如果使用數(shù)據(jù)處理指令或者多寄存器調(diào)用指令,也會(huì)轉(zhuǎn)移到Thumb指令中去。如果例程處理完畢,也將返回ARM指令中。
必須明確的是Thumb指令系統(tǒng)必須包括ARM代碼,至少是初始化和例程入口部分。
Thumb指令集是ARM指令集的子集,Thumb只使用有限的ARM寄存器。Thumb指令一般可以完全訪問(wèn)通用寄存器R0~R7(稱為低寄存器),R13用作堆棧指針,R14用作鏈接寄存器,R15用作PC。Thumb中的一些指令可以訪問(wèn)其余的寄存器如R8~R15(稱為高寄存器),算術(shù)運(yùn)算和邏輯運(yùn)算指令可以訪問(wèn)CPS2中的標(biāo)志位。
大部分的Thumb 指令與ARM指令類似,不過(guò)在寄存器、立即數(shù)、尋址等方面會(huì)有些差異,Thumb和ARM指令性計(jì)劃集的區(qū)別一般有以下幾點(diǎn):
l轉(zhuǎn)移指令;
l數(shù)據(jù)傳送指令;
l單寄存器Load和Store指令;
l多寄存器Load和Store指令。
Thumb指令集沒(méi)有協(xié)處理器指令、信號(hào)量(samaphore)指令以及訪問(wèn)CPSR或SPSR的指令。
?。?) 轉(zhuǎn)移指令
轉(zhuǎn)移指令用于:
l向后轉(zhuǎn)移形成循環(huán);
l條件結(jié)構(gòu)向前轉(zhuǎn)移;
l轉(zhuǎn)向子程序;
l處理器從Thumb狀態(tài)切換到ARM狀態(tài)。
程序相對(duì)轉(zhuǎn)移,特別是條件轉(zhuǎn)移與在ARM狀態(tài)下相比,在范圍上有更多的限制,轉(zhuǎn)向子程序只能是無(wú)條件轉(zhuǎn)移。
?。?) 數(shù)據(jù)處理指令
這些指令對(duì)通用寄存器進(jìn)行操作,在許多情況下,操作的結(jié)果必須放入其中一個(gè)操作數(shù)寄存器中,而不是第3個(gè)寄存器中。數(shù)據(jù)處理操作比ARM狀態(tài)更少,訪問(wèn)寄存器R8~R15受到一定限制。
MOV或ADD指令可訪問(wèn)寄存器R8~R15,數(shù)據(jù)處理指令總是更新CPS2中的ALU狀態(tài)標(biāo)志。訪問(wèn)寄存器R8~R15的Thumb數(shù)據(jù)處理指令不能更新標(biāo)志。
(3) 單寄存器Load和Store指令
這些指令從存儲(chǔ)器讀取1個(gè)寄存器值,或把1個(gè)寄存器值存儲(chǔ)到存儲(chǔ)器。在Thumb狀態(tài)下,這些指令只能訪問(wèn)寄存器R0~R7。
?。?) 多寄存器Load和Store指令
?。蹋模秃停樱裕蛯⑷魏畏秶鸀椋遥啊遥返募拇嫫髯蛹瘡拇鎯?chǔ)器讀取以及存儲(chǔ)到存儲(chǔ)中。
?。校眨樱群停校希兄噶钍褂枚褩V羔槪≧13)作為基址實(shí)現(xiàn)滿遞減堆棧。除可傳送R0~R7外,PUSH還可以用于存儲(chǔ)連接寄存器,POP可以用于讀取程序指針。
Tuhmb指令主要有以下幾類指令組成:Tuhmb Load/Store類指令;Thumb數(shù)據(jù)運(yùn)算類指令;Thumb轉(zhuǎn)移類指令,以及軟件中斷指令。
3.3.1 Thumb Load/Store類指令
1 Thumb單寄存器Load/Store指令
Thumb單寄存器傳送類指令是ARM單寄存器傳送類指令的一個(gè)子集,和ARM有相同的指令格式。
Thumb單寄存器傳送指令分以下4種:
?。?) LDR和STR—立即數(shù)偏移
功能:讀取寄存器和存儲(chǔ)寄存器。寄存器的地址用一個(gè)寄存器的數(shù)偏移量指明,立即數(shù)偏移的半字和字節(jié)讀取是無(wú)符號(hào)的。
格式:
?。疾僮鞔a>Rd,[Rn,《#immed_5*N》]
?。疾僮鞔a>包括:LDR,LDRB,STR,STRH和STRH指令
其中:
H 指明無(wú)符號(hào)半字傳送。
B 指明無(wú)符號(hào)字節(jié)傳送
RD 讀取和存儲(chǔ)寄存器。Rd必須在R0—R7范圍內(nèi)
RN 基址寄存器.Rn必須在R0—R7范圍內(nèi)
Immed_5*N 偏移量。Immed_5是一個(gè)表達(dá)式,其中值在0--31范圍內(nèi),在匯編時(shí)結(jié)果是的N倍數(shù)。
對(duì)字節(jié)傳送,N=1
對(duì)半字傳送,N=2az
對(duì)字傳送, N=4
注釋:
字傳送的地址必須可被4整除,半字傳送的地址必須可被2整除。
若系統(tǒng)中有系統(tǒng)協(xié)處理器(CP15),則可允許對(duì)準(zhǔn)檢查。若允許對(duì)準(zhǔn)檢查,則非對(duì)準(zhǔn)的傳送會(huì)引起對(duì)準(zhǔn)異常
若系統(tǒng)沒(méi)有協(xié)處理系統(tǒng)器(CP15)或禁止對(duì)準(zhǔn)檢查,則:
非對(duì)準(zhǔn)讀取使Rd不可靠
非對(duì)準(zhǔn)存使存儲(chǔ)器的2個(gè)或4個(gè)字節(jié)不可靠。對(duì)半字存儲(chǔ),不可靠的存儲(chǔ)器位置是address AND NOT 0x1; 于字存儲(chǔ)器,則是address AND NOT 0x3
例:
LDR R3,[R5,#0] ;(R5)→R3
STRB R0,[R3,#3] ;(R0)→((R3)+31)
STRH R7,[R3,#16] ;(R7)→((R3)+16)
LDRH R2,[R4,#Label—{PC}]
?。?) LDR和STR---寄存器偏移
功能:讀取寄存器和存儲(chǔ)寄存器。存儲(chǔ)器的地址用一個(gè)寄存器的基于寄存器偏移指明存儲(chǔ)器地址。
格式:
《操作碼》Rd,[Rn,Rm]
《操作碼》是下列情況之一:
讀取寄存器,4字節(jié)字
存儲(chǔ)寄存器,2字節(jié)字
讀取寄存器,2字節(jié)無(wú)符號(hào)半字
讀取寄存器,2字節(jié)字有符號(hào)半字,有符號(hào)位擴(kuò)展(即高位字節(jié)與符號(hào)字節(jié)相同)
存儲(chǔ)寄存器,2字節(jié)半字
讀取寄存器,無(wú)符號(hào)半字
讀取寄存器,有符號(hào)半字,有符號(hào)位擴(kuò)展(即高位字節(jié)與符號(hào)位相同)
存儲(chǔ)寄存器,字節(jié)
含偏移量的寄存器,Rm必須在R0~R7范圍內(nèi)
注釋:
同3.3.1節(jié)第1條指令。
例:
LDR R2,[R1,R5]; ((R1)+(R5))---R2
STRH R0,[R0,R1]; (R0)---((R0)+(R1))
STRB R1,[R7,R0]; (R1)---(R7)+(R0)
?。?) LDR----PC相對(duì)偏移
功能:讀取寄存器和存儲(chǔ)器。存儲(chǔ)器中的地址用中內(nèi)容的立即數(shù)偏移指明。字節(jié)碼結(jié)構(gòu):
格式:
LDR Rd,[PC,#immed_8*4]
LDR Rd,Label
其中:
immed_8*4偏移量。它是一個(gè)表達(dá)式,取值(在匯編時(shí))為4的整數(shù)倍,范圍在0~1020內(nèi)。
Label 程序相對(duì)偏移表達(dá)式。必須在當(dāng)前指令之后且范圍內(nèi)。
注釋:
同3.3.1節(jié)第1條指令
例:+
LDR R2,[PC,#1016]; ((PC)+1026)---R2
LDR R5,localdata
?。?) LDR和STR---SP相對(duì)偏移
功能:讀取寄存器和存儲(chǔ)寄存器。存儲(chǔ)器的地址用中內(nèi)容的立即數(shù)偏移指明。
格式:LDR Rd,[SP,#immed_8*4]
STR Rd,[SP,#immed_8*4]
其中:
immed_8*4
偏移量。它是一個(gè)表達(dá)式,取值(在匯編時(shí))為4的整數(shù)倍,范圍在0~1020內(nèi)。
注釋:
同3.3.1節(jié)第1條指令。
例:
LDR R0,[SP,#920]; ((SP)+920)---R0
STR R1,[SP,#20]; (R1)---(SP)+20
2 Thumb多寄存器指令
功能:Load和多個(gè)Store寄存器
格式:(1)LDMIA Rn!, 《Reglist》 (2)STMIA Rn!,《Reglist》
其中:
Reglist 低寄存器或低寄存范圍的,用逗號(hào)隔開的列表。列表中至少有一個(gè)寄存器。
Rn 目的寄存器,必須是低于寄存器
注釋:
(1)寄存器以數(shù)字順序取或存儲(chǔ)。最低數(shù)字的寄存器在的初地址中。的值以中寄存器個(gè)數(shù)的4倍增加。
(2)若在Rn寄存器列表中,則
對(duì)于LDMIA指令,Rn的最終值是讀取的值,不是增加后的地址。
對(duì)于STMIA指令,Rn的終值有如以下兩種情況:
---若是寄存器列表中最低的寄存器,則的存儲(chǔ)值為初值;
---其他情況則不可預(yù)知。
例:
LDMIA R3!,(R0,R4); (R0)---(R3),(R4)---(R3)+4; (R3)+8---R3
STMIA R0!,(R3,R5,R7);((R0)--R3,((R0)+4)---R5,
??;((R0)+8)---R7,(R0)+12---R0
3 堆棧指令
功能:低寄存器和可選的LR進(jìn)棧,低寄存器和可選的PC出棧。
格式:POP {《REglist》{,PC}}
PUSH {《Reglist》{,LR}}
其中:Reglist
低寄存器或寄存器范圍的,用逗號(hào)隔開的列表。
注釋:
?。?)Thumb堆棧是滿遞減堆棧,向下增長(zhǎng),且SP指向堆棧的最后入口。
?。?)寄存器以數(shù)字順序存儲(chǔ)在堆棧中。最低數(shù)字的寄存器其地址最低。
?。?)POP{Reglist}這條指令引起處理器轉(zhuǎn)移到從堆棧彈出給PC的地址,這通常是從子程序返回,其中LR在子程序開頭壓進(jìn)堆棧。
?。?)對(duì)于ARMv5T及以上的版本,則
若讀到PC中的值的位[1:0]是b00,則處理器變換到ARM狀態(tài)
位[1:0]不允許的值b10。
(5)條件碼標(biāo)志。這些指令不影響條件碼標(biāo)志。
例:
PUSH {R0,R4---R7} ;R0,R4---R7進(jìn)棧-
PUSH {R0,LR}
POP {R2,R5}
POP {R0---R7,PC}
3.3.2 Thumb數(shù)據(jù)運(yùn)算類指令
Thumb數(shù)據(jù)運(yùn)算指令有以下8種:
1 ADD和SUM-----低寄存器
功能:2個(gè)寄存器的,內(nèi)容相加或相減,結(jié)果放到第3個(gè)寄存器中。
格式:《操作碼》Rd,Rn,Rm
《操作碼》包括:ADD,SUB指令。
其中:
Rd 目的寄存器。必須是低寄存器
Rn 第操作寄存器。必須是低寄存器
Rm 第2操作寄存器。必須是低寄存器。
注釋:這些指令更新標(biāo)志N,Z,C,V。
例:ADD R3,R1,R5。
2 ADD和SUB----小整數(shù)
功能:寄存器中的值加上或減去一個(gè)小整數(shù),結(jié)果放在另一個(gè)不同寄存器中。
格式:《操作碼》 Rd,Rn,# 《3位立即數(shù)》
《操作碼》包括:ADD,SUB指令。
其中:
Rd目的寄存器。必須是低寄存器(R0~R7)
Rn第1操作數(shù)寄存器。必須是低寄存器(R0~R7)
Expr3 表達(dá)式,為取值范圍在—7~+7內(nèi)的整數(shù)。
注釋:
這些指令更新標(biāo)志N,Z,C,V.
例:SUB R0,R4,#5 ; (R4)---5---R0
3 ADD,SUB,MOV,CMP----大整數(shù)
功能:寄存器中的值對(duì)于一個(gè)大事整數(shù)進(jìn)行ADD,SUB,MOV,CMP運(yùn)算,結(jié)果放在另一個(gè)不同的寄存器中。
格式:
《操作碼》 Rd|Rn,#《8位立即數(shù)》
《操作碼》包括:ADD,SUB,MOV,CMP指令。
其中:
Rd,Rn 目的寄存器。必須是低寄存器(R0~R7)
Expre8 表達(dá)式,為取值范圍在—255~+255內(nèi)的整數(shù)。
注釋:這些指令更新標(biāo)志N,Z,C,V.
例:
ADD R7,#201
ADD R1,vc+4 ; vc+4匯編時(shí)必取值范圍為—255~+255的整數(shù)
4 ADD,MOV,CMP----高或低寄存器
功能:將寄存器中值進(jìn)行運(yùn)算,結(jié)果送回到第一操作數(shù)寄存器。
格式:
《操作碼》 Rd|Rn,Rm
《操作碼》包括:ADD,MOV,CMP指令。
其中:
Rd,Rn目的寄存器,也是第1操作數(shù)寄存器。
Rm第二操作數(shù)寄存器。
Rd,Rn,Rm使用高或低寄存器,當(dāng)和是低寄存器,指令“ADD,Rd,Rm”匯編成“ADD Rd,Rm”。
注釋:
若Rd,Rn和Rm是低寄存器,則更新條件碼標(biāo)志N,Z,C和V,其他情況下這些標(biāo)志不受影響。
例:ADD R0,R8
ADD R2,R4 ; 等價(jià)于“ADD R2,R2,R4”,不影響標(biāo)志。
5 ADD和SUB----SP
功能:SP加上或減去立即數(shù)常量。
格式:
《操作碼》SP,#《expr》
《操作碼》包括:ADD,SUB指令。
其中:
expr表達(dá)式,取值范圍在—508~+508內(nèi)的4倍數(shù)的整數(shù)。expr為負(fù)值的ADD指令匯編成相應(yīng)的帶正數(shù)常量的指令。expr為負(fù)值的指令匯編相應(yīng)的帶正數(shù)常量的ADD指令。
注釋:
這條指令指示不影響條件碼標(biāo)志。
例:
ADD SP,#312
SUB SP,#96
SUB SP,#abc+8; abc+8匯編時(shí)必須取值為范圍在---508~+508內(nèi)4的整數(shù)倍。
6 ADD---PC或SP相對(duì)偏移
功能:SP或PC值加上一立即相對(duì)數(shù)常量,結(jié)果放入低寄存器。
格式:
ADD Rd,Rp,#《expr》
其中:
Rd 目的寄存器。Rd必須在R0~R7范圍內(nèi)。
Rp SP|PC.RP是PC,則使用值是(當(dāng)前指令地址+4)AND&FFFFFFC。
Expr 表達(dá)式,取值為范圍在0~1020的4整倍數(shù)。
注釋:
這條指令不影響條件碼標(biāo)志。
例:
ADD R2,SP,#64
ADD R6,PC,#980
ADD R0,PC,#lit—{PC}; lit—{PC}必須取值成范圍在0~1020的4的
;整數(shù)倍
7 ASR,LSL,LSR和ROR運(yùn)算
功能:移位和循環(huán)移位操作。這些指令可使用寄存器中的值或立即數(shù)移位。
格式1:
《操作碼》Rd,Rn,《#immed_5》
其中:
《操作碼》是下列的任何一種:
ASR算術(shù)右移。將寄存器中的內(nèi)容看作補(bǔ)碼形式的有符號(hào)整數(shù)。將符號(hào)位移拷貝到空位。
LSL邏輯左移,移入為0。
LSR邏輯右移,移入為0。
ROR循環(huán)右移。將寄存器右移出的位循環(huán)移回到左端。ROR僅能與寄存器控制的移位一起使用。
Rd立即數(shù)移位的目的寄存器。必須在R0~R7范圍內(nèi)。
Rn立即數(shù)移位的源寄存器。Rn必須在R0~R7范圍內(nèi)。
Immed_5 立即數(shù)移位量。它是一個(gè)取值為整數(shù)的表達(dá)式。整數(shù)的范圍如下:
《操作碼》若是LSL,ROR,則為0~31;
其余則為1~32。
格式2:
《操作碼》 Rd|Rn,Rs|Rm
其中:
《操作碼》同格式1。
Rd 寄存器控制移位的源寄存器。Rd必須在R0~R7范圍內(nèi)。
Rs 在控制移位中包含移位量的寄存器。Rs必須在R0~R7范圍內(nèi)。
注釋:
(1)立即數(shù)移位(格式1)。
指令從Rn取值,并對(duì)其進(jìn)行移位,結(jié)果放回Rd中。
?。?)寄存器控制移位(格式2)
這些指令從Rd中取值,并對(duì)其進(jìn)行移位,結(jié)果放回Rd.只有Rs的最低的效數(shù)字節(jié)可用作移位量。
對(duì)于除ROR以外的所有指令,則有
若移位量為32,則Rd清零。最后移出的位保留在標(biāo)志C中。
若移位量大于32,則Rd和標(biāo)志C均被清零。
?。?)條件碼標(biāo)志
這些指令根據(jù)結(jié)果更新標(biāo)志N與Z,且不影響標(biāo)志V。對(duì)于標(biāo)志C,若移位量是零,則它不受影響,其他情況下,它包含源寄存器的最后移出位。
例:ASR R3,R5
LSR R0,R2,#6
LSR R%,R5,av; av的值必須在匯編時(shí)取成在1~32范圍內(nèi)的整數(shù)
LSL R0,R4,#0 ;除了不影響標(biāo)志C和V外,同“MOV R0,R4”
8 其他運(yùn)算類指令
格式1:
《操作碼》 Rd|Rn,Rm|Rs
《操作碼》 包括:MOV,MVN,CMN,TST,ADC,SBC,NEG,MUL,AND,EOR,ORR,BIC指令。
《操作碼》Rd|Rn,#expr
《操作碼》包括:MOV,CMP指令。
Rd Rn 目的寄存器,它也是包含第1條指令操作數(shù)。
Rm Rs 第二操作數(shù)寄存器。
Expr 表達(dá)式,其值范圍為在1~255內(nèi)的整數(shù)。
表3~5 Thumb數(shù)據(jù)處理指令
助記符含義動(dòng)作
ADC Rd,RmADD Rd,Rn,RmADD Rd,Rn,#0to7ADD Rd,#0to255AND Rd,RmASR Rd,Rm#1to32ASR Rd,RaBIC Rd,RaCMN Rn,RmCMP Rn,#0to255CMP Rn,RmEOR Rd,RmLSL Rd,Rm,#0to31LSL Rd,Rm,#1to32LSR Rd,Rm,#1to32LSR Rd,RsMOV Rd,#0to255MOV Rd,RnMUL Rd,RmMVN Rd,RmNEG Rd,RmORR Rd,RmRORRd,RsSBC Rd,RmSUBRd,Rn,RmSUB Rd,Rn,RmSUB Rd,#0to255TST Rn,Rm帶進(jìn)位加法加法加法加法邏輯與算術(shù)右移算術(shù)右移位清除比較非值比較比較邏輯異或邏輯左移邏輯左移邏輯右移邏輯右移傳送傳送乘法傳送非取負(fù)邏輯或循環(huán)右移帶進(jìn)位減法減法減法減法測(cè)試Rd---Rd+Rm+進(jìn)位標(biāo)志Rd---Rn+RmRd---Rn+3位立即數(shù)Rd---Rd+8位立即數(shù)Rd---Rd AND RmRd---Rm ASR5位立即數(shù)Rd---Rd ASR RsRd---Rd AND NOT RmRn+Rm更新標(biāo)志Rn—8后立即更新標(biāo)志Rn—RmRd---Rd EOR RmRd---Rm LSL 5位立即數(shù)Rd---Rm LSL RsRd---Rd LSR 5位立即數(shù)Rd---Rd LSR RsRd---8位立即數(shù)Rd---RnRd---Rm*RdRd---NOT RmRd---0--RmRd---Rd OR RmRd---Rd ROR RsRd--Rd-Rm-NOT(進(jìn)位標(biāo)志)Rd---Rn--RmRd---Rn—3位立即數(shù)Rd---Rn—8立即數(shù)Rn AND Rm后更新標(biāo)志
注釋:
(1)除了“CMP RN,Rm”和“MOV Rd,Rm”指令中的和可以是中的Rn,Rm任何寄存器外,其余指令只能使用低寄存器(R0~R7)
?。?)條件碼標(biāo)志:
ADC,SBC,CMP,CMN和NEG指令更新標(biāo)志N,Z,C和V.
AND,EOR,ORR,BIC指令根據(jù)結(jié)果更新標(biāo)志N和Z
MVN,TST,“MOV Rd,#expr”和指令更新標(biāo)志N和Z,對(duì)標(biāo)志C和V影響。
“MOV Rd,Rm”指令表現(xiàn)如下:
若Rd或Rm是高寄存器(R8~R15),則標(biāo)志不受影響。
若Rd或Rm都是低寄存器(R0~R7),則更新標(biāo)志N和Z,且清除清除標(biāo)志C和V。
MUL更新標(biāo)志N和Z。在ARM v4及前版本中,MUL會(huì)使標(biāo)志C和V不可靠。在ARM v5及以后的版本中,MUL不影響標(biāo)志C和V。
注意:可用移位為0來(lái)使用LSL,實(shí)現(xiàn)在低寄存器之間傳送而不清除標(biāo)志C,V。
例:
ADC R2,R4
CMP R7,R12 ; 指令“CMP Rn,Rm”允許高寄存器
MOV R3,#0
TST R2,R4
3.3.3 Thumb轉(zhuǎn)移指令
Thumb 轉(zhuǎn)移指令主要分以下幾類:
1 B指令
格式1:
B 《條件碼》 《Label》
格式2:
B 《Label》
其中:
Label 程序相對(duì)偏移表達(dá)式。通常是在同一代碼塊內(nèi)標(biāo)號(hào)。
若使用條件碼,則必須在當(dāng)前指令的—254~+254字節(jié)范圍內(nèi);
若指令是無(wú)條件,則Label必須中正負(fù)2KB范圍內(nèi)。
Thumb B指令的條件碼如表3--6所示。
表3—6 Thumb B指令
條件代碼含義標(biāo)志位狀態(tài)顯示
EQNECS/HSCC/LOMIPLVSVCHILSGELTGTLE相等/是否為0不等進(jìn)位置/大于進(jìn)位清零/小于結(jié)果為負(fù)結(jié)果為正溢出無(wú)溢出大于小于大于等于小于等于大于小于等于 Z置位Z清零C置位C清零N置位N清零V置位V清零C置位且Z清零C清零或Z置位N等于VN不等于VZ清零或N等于VZ置位或N不等于V
注釋:
若條件碼滿足或不使用條件碼,則B指令引起處理器轉(zhuǎn)移到Label.
例:
B dloop
BEQ sectB
2 BL,BLX指令
格式:
BL{X} 《Label》
其中:
Label 程序相對(duì)轉(zhuǎn)移表達(dá)式。
注釋:
BL指令將下一條指令的地址拷貝到R14(LR鏈接寄存器),并引起處理器轉(zhuǎn)移到Label。機(jī)器級(jí)指令不能轉(zhuǎn)移到當(dāng)前正負(fù)4MB指令以外的地址。必要時(shí),ARM鏈接器插入代碼(veneer)以允許更長(zhǎng)的轉(zhuǎn)移。
BL指令實(shí)際上分為2條指令,1條指令H=0,它把11位偏移量左移12位,加上現(xiàn)行PC,寫入中R14(LR),另一條指令H=1,它把LR加上11位偏移量乘2寫入PC,同時(shí)把下一條指令寫入R14中。
BLX指令可用于:
拷貝下一條指令的地址到R14(LR鏈接寄存器)。
引起處理器轉(zhuǎn)移到Label或Rm存儲(chǔ)的地址
如果Rm的位[0]清零,或使用“BLX Label”形式,則指令集切換到ARM狀態(tài)。BLX指令適用于ARM v5T指令系統(tǒng)及以上版本。
例:
B extract
3 BX,BLX指令
格式:
B{L}X Rm
其中:
Rm 裝有目的地址的ARM寄存器,m=0~15。Rm的位[0]I不用于地址部分。若Rm位清零。則
位[1]也必須清零;
指令清零CPSR中的標(biāo)志T,目的地址的代碼被解釋為ARM代碼。
注釋:
BX指令引起處理器轉(zhuǎn)移到Rm存儲(chǔ)的地址。若Rm的位[0]置位,則指令集切換到Hhnmb狀態(tài)。
BLX指令用來(lái)在Thumb程序中調(diào)用ARM或者子程序,地址由Rm指定。從子程序返回,用BX R14指令。
例:
BX R5
BLX R6
3.3.4 Thumb軟件中斷和斷點(diǎn)指令
1 Thumb軟件中斷指令
功能:Thumb的SWI指令類似于ARM SWI指令。該指令執(zhí)行后的操作是:
?。?)將下一條Thumb指令地址保存進(jìn)R14_svc。
(2)PSR的內(nèi)容保存進(jìn)SPSR_svc;
?。?)禁止IRQ中斷,清除Thumb位,進(jìn)入SVC模式;
?。?)PC指向0x08。
返回指令恢復(fù)Thumb執(zhí)行的狀態(tài)。
格式:SWI 《immed_8》
其中:
immed_8 符號(hào)表達(dá)式,其取值范圍為的整數(shù)。
SWI指令引起SWI異常。這意味著處理器狀態(tài)切換到ARM態(tài),處理器模式切換到管理模式的,CPSR保存到管理模式中,執(zhí)行轉(zhuǎn)移SWI到向量地址。
處理器忽略immed_8,但immed_8出現(xiàn)在指令操作碼的位[7:0]中。而異常處理程序用它來(lái)確定正在請(qǐng)求何種服務(wù)。
注釋:
這條指令不影響條件碼標(biāo)志。
例:
SWI 12
2 Thumb斷點(diǎn)指令
格式:
BRKT immed_8
其中:
immed_8 符號(hào)表達(dá)式,取值范圍為0~255的整數(shù)。
注釋:
BKPT(BreakPoinT)指令引起處理器進(jìn)入調(diào)試模式。調(diào)試工具利用這一特點(diǎn)調(diào)查到達(dá)特定地址的指令時(shí)的系統(tǒng)狀態(tài)。
盡管immed_8出現(xiàn)在指令操作碼的位[7:8]中,處理器忽略immed_8。調(diào)試器用它來(lái)存儲(chǔ)有關(guān)斷點(diǎn)的附加消息。
BKPT指令適用于ARM v5T指令系統(tǒng)及以上版本。
例:
BKPT 67
BKPT 2_10110
3.3.5 Thumb指令示例
1 從Thumb狀態(tài)到ARM狀態(tài)
ADR R1,oct of Thumb
MOV R11,R1
BX R11
……
ALIGN
CODE32
Out of Thumb ……
2 ARM和Thumb指令編寫的比較
本節(jié)最后通過(guò)比較ARM和Thumb指令編寫“Hello Word”程序,示例Thumb指令的編寫。從下面的例子中可以看到,指令Thumb的執(zhí)行必須由ARM狀態(tài)轉(zhuǎn)向Thumb狀態(tài),通常BX指令完成。另外在Thumb指令前必須有CODE16偽指令指示匯編器以下指令為Thumb指令。
(1) ARM指令編寫的“Hello Word”程序
AREA HelloW,CODE,READONLY
SWI_WriteC EQU &0; SWI中斷入口
SWI_Exit EQU &11
ENTRY
START ADR R1,TEXT
LOOP LDRB R0,[R1],#1
CMP R0,#0
SWINE SWI_WriteC;參數(shù)&0完成顯示成輸出
BNE LOOP
SWI SWI_Exit;參數(shù)&11返回
TEXT = “Hello Word”;&0a,&0d,0
END
(2) Thumb指令編寫的“Hello Word”程序
AREA HelloW_Thumb,CODE,READONLY
SWI_WriteC EQU&0
SWI_Exit EQU&11
ENTRY
CODE32 ;指示以下為ARM指令
ADR R0,START+1
BX R0 ;轉(zhuǎn)向Thumb程序
CODE16 ;指示以下指令為Thumb指令
START ADR R1,TEXT
LOOP LDRB R0,[R1]
ADD R1,R1,#1
CMP R0,#0
BEQ DONE ;轉(zhuǎn)向Thumb子程序DONE
SWINE SWI_WriteC
B LOOP
DONE SWI SWI_Exit
ALIGN
TEXT DATA
= “Hello World”,&0d,0
END
3.4 ARM宏匯編
本節(jié)將詳盡地介紹匯編器所提供的特征,包括偽指令,宏匯編以及指示標(biāo)志。
3.4.1 預(yù)定義變量
1 預(yù)定義變量的寄存器的協(xié)處理器名
ARM匯編器對(duì)ARM的寄存器進(jìn)行了預(yù)定義,所有的寄存器和協(xié)處理器都是大小寫敏感的。預(yù)定義的寄存器如表3—7所示。
?。?) 定義的寄存器名
R0~R15
R0~r15
a1~a4
v1~v8
sp和SP
Ir和LR
Pc和PC
Sl和SL
表3---7為ARM寄存器列表及含義
寄存器特殊定義其它定義含義
R15R14R13R12R11R10R9R8R7R6R5R4R3R2R1R0V8V7V6V5V4V3V2V1a4a3a2a1PCLRSPIPFPSLSBWR程序計(jì)數(shù)器鏈接寄存器堆棧指針程序調(diào)用暫存寄存器變量寄存器8/幀指針(ARM狀態(tài))變量寄存器7/堆棧上限指針(ARM)變量寄存器6/基址寄存器(進(jìn)程ID/重入/共享庫(kù)中)變量寄存器5變量寄存器4(Thumb狀態(tài)工作寄存器)變量寄存器3變量寄存器2變量寄存器1參數(shù)/結(jié)果/暫寄存器4參數(shù)/結(jié)果/暫寄存器3參數(shù)/結(jié)果/暫寄存器2參數(shù)/結(jié)果/暫寄存器1
R0~R3通常用來(lái)傳遞參數(shù)和保存結(jié)果,也可以保存子程序調(diào)用的中間結(jié)果,在ARM狀態(tài)下,R12(也稱為IP)通常也保存子程序調(diào)用的中間結(jié)果。R14~R11通常保存程序的局部變量,也可以用V1~V8表示,但是V1~V4只能在Thumb狀態(tài)下使用。
R12~R15一般有特殊用途,也通常稱為IP,SP,LR,PC。
?。?)定義的程序狀態(tài)寄存器名
cpsr和CPSR
spsr和SPSR
?。?)定義的浮點(diǎn)數(shù)寄存器名
f0~f7
F0~F7
?。?)定義的協(xié)處理器名
p0~p15
c0~c15
2 內(nèi)置變量
表3—8列出了ARM匯編器所定義的內(nèi)置變量,值得注意的是內(nèi)置變量的設(shè)置不能用SETA,SETL,或SETS等表示詞來(lái)設(shè)置,只能用字符或條件表達(dá)式來(lái)設(shè)置。例如:
IF {ARCHITECTURE}=“4T”
表3—8 變量含義
(PC )或者(VAR)或者@(TRUE)(FALSE)(OPT)(CONFIG)(ENDIAN)(CODESIZE)(CPU)(ARCHITECTURE)(PCSTOREOFFSET)當(dāng)前指令的地址存儲(chǔ)區(qū)計(jì)數(shù)器的當(dāng)前值邏輯常量為真邏輯常量為假當(dāng)前設(shè)置列表選項(xiàng),OPT用來(lái)保存當(dāng)前列表選項(xiàng),改變選項(xiàng)值,恢復(fù)設(shè)置它的原始值如果匯編器在ARM模式下值為32,如果匯編在Thumb 模式下值為16如果匯編器在big—endian模式下為big,如果匯編器在某些方面little—endian模式下值為little如果匯編Thumb代碼值為16,否則為32選定的CPU符號(hào),如果沒(méi)有說(shuō)明,則為genericARM選定的ARM架構(gòu)的值,3,3M,4,4T,4TxMSTRpc,[…]或STM Rb,(…PC)的地址和PC的存儲(chǔ)值之間的偏移量
3.4.2 偽指令
ARM匯編器采用兩類偽指令,一類是為ARM偽指令,另一類是Thumb偽指令。在ARM狀態(tài)下可以使用的偽指令如下:
1 ADR偽指令
功能:把程序相關(guān)的或寄存器相關(guān)的地址調(diào)進(jìn)寄存器中。
格式:ADR{condition} register,expression
其中:
register 讀取的寄存器。
Expression 程序相關(guān)的或寄存器相關(guān)的表達(dá)式,必須是:
255字節(jié)以內(nèi)的非字對(duì)準(zhǔn)地址;
1020字節(jié)以內(nèi)的字對(duì)準(zhǔn)地址。
寄存器相關(guān)的表達(dá)式由1個(gè)寄存器加或減1個(gè)數(shù)字常數(shù)組成(見(jiàn)“ⅴ”或者M(jìn)PA介紹。)程序相關(guān)的表達(dá)式由PC加或減1個(gè)數(shù)字組成,一般它可為標(biāo)號(hào)或加減數(shù)字表達(dá)式。
注釋:
ADR偽指令通常匯編成一條指令,匯編器產(chǎn)生一條ADD或SUB指令以讀入地址。如果表達(dá)式是關(guān)于程序相關(guān)的,讀取地址只能是ADR偽指令所在代碼所在的地址。
例:
start MOV R0,#10
ADR R4,start ; 等同于SUB,R4,PC,#0xc
2 ADRL偽指令
功能:與ADR功能類似,但是可以調(diào)進(jìn)范圍更廣的地址。
格式:
ADR{condition} register,expression
其中:
register 讀取的寄存器。
Expression 程序相關(guān)的或相關(guān)的表達(dá)式,必須是:
64KB以內(nèi)的非對(duì)準(zhǔn)地址;
256KB以內(nèi)的字對(duì)準(zhǔn)地址。
注釋:
ADRL偽指令通常匯編成2條指令,即使地址在第1條指令已經(jīng)產(chǎn)生,也會(huì)產(chǎn)生1條冗余指令。如果表達(dá)式是關(guān)于程序表達(dá)式相關(guān)的,讀取地址只能是ADRL偽指令所在的代碼段所在的地址。注意:該指令只能在ARM狀態(tài)下使用,在Thumb狀態(tài)下不能使用。
例:
start MOV R0,#10
ADRL R4,start+60000;等同于ADD R4,PC,#0xE800
等同于ADD R4,R4,#0x254
3 LDFD偽指令
功能:將一個(gè)雙精度的浮點(diǎn)常量放進(jìn)
格式:
LDFD{condition} fp-register,=expression
其中:
condition 可選的條件代碼。
fp-register 讀取的浮點(diǎn)寄存器。
Expression 浮點(diǎn)常量。匯編器通常把放在一個(gè)庫(kù)中,用LDFD偽指令讀進(jìn)浮點(diǎn)寄存器中,該浮點(diǎn)常量用2個(gè)字存放。PC與該常量的偏移量不得超過(guò)4KB。
注釋:
浮點(diǎn)數(shù)常量的范圍是:
最大值 1.79769313486231571e+308
最小值2.22507385850720138e—308ADR
注意;只有系統(tǒng)中有浮點(diǎn)加速器FPA(Floating Point Accelerator)時(shí),才能使用該指令。
例:
LDFD f1,=3.12E106
4 LDFS 偽指令
功能:將一個(gè)單精度的浮點(diǎn)數(shù)常量放進(jìn)一個(gè)浮點(diǎn)數(shù)寄存器。
格式:
LDFS{condition} fp-register,=expression
其中:
condition 可選的條件代碼。
fp-register 讀取的浮點(diǎn)寄存器。
Expression 浮點(diǎn)常量。匯編器通常把該常量放在一個(gè)庫(kù)中,用LDFD偽指令讀進(jìn)浮點(diǎn)寄存器中,該浮點(diǎn)常量用2個(gè)字存放。PC與該常量的偏移量不得超過(guò)4KB。
注釋:
浮點(diǎn)數(shù)常理的范圍是:
最大值:3.40282347e+38F
最小值:1.17549435e—38F
注意:只有系統(tǒng)中有一個(gè)浮點(diǎn)加速器時(shí),才能使用該指令。
例:
LDFS f1,=3.12E---6
5 LDR 偽指令
功能:將一個(gè)32位常量或地址讀取至寄存器。
格式:
LDR{condition} register,=[expression|Label-expression]
其中:
condition 可選的條件代碼。
register 讀取的寄存器。
expression 數(shù)字常量:
如果該數(shù)字常量在MOV或MVN指令的范圍中,匯編器會(huì)產(chǎn)生合適的指令;
如果該數(shù)字量不在MOV或MVN指令的范圍中,匯編器把該常量于程序后,用程序相關(guān)的LDR偽指令讀取,PC與該常量的偏移量不得超過(guò)4KB。
Label-expression 程序相關(guān)的或外部的表達(dá)式。匯編器將其存放在程序后的常量庫(kù)(稱為文字池(literal pool))中,用程序相關(guān)的LDR偽指令讀取,PC與與該常量的偏移量不得超過(guò)4KB。
注釋:
LDR偽指令的使用有兩個(gè)目的:
對(duì)于不能被MOV和MVN指令所讀取的立即數(shù),將其變成常量,進(jìn)行讀取:
將一個(gè)程序相關(guān)的或外部的表達(dá)式讀取進(jìn)寄存器中。
例:
LDR R1, =0xfff
LDR R2, =place
6 NOP偽指令
功能: 產(chǎn)生空操作代碼。即:MOV R0,R0.
格式:
NOP
注釋:
該指令不能帶條件使用,也不能改變條件碼.
評(píng)論
查看更多