ARM指令系統(tǒng)特點
ARM指令系統(tǒng)屬于RISC指令系統(tǒng)。標(biāo)準(zhǔn)的ARM指令每條都是32位長,有些ARM核還可以執(zhí)行Thmub指令集,該指令集是ARM指令集的子集,每條指令只有16位。
1 數(shù)據(jù)類型
ARM處理器一般支持下列6種數(shù)據(jù)類型:
l8位有符號字節(jié)類型數(shù)據(jù);
l8位無符號字節(jié)類型數(shù)據(jù);
l16位有符號半字類型數(shù)據(jù);
l16位無符號半字類型數(shù)據(jù);
l32位有符號字類型數(shù)據(jù);
l32位無符號字類型數(shù)據(jù);
有些ARM處理器不支持半字和有符號字節(jié)數(shù)據(jù)類型。在ARM內(nèi)部,所有指令都是32操作數(shù)據(jù)。短的數(shù)據(jù)數(shù)據(jù)類型只有在數(shù)據(jù)傳送類指令中才被支持當(dāng)1個字節(jié)數(shù)據(jù)取出后,被擴展到32位,在內(nèi)部數(shù)據(jù)處理時,作為32位的什進(jìn)行處理,并且ARM指令以字為邊界。所有Thumb指令都是16位指令時,并且以2個字節(jié)為邊界。
ARM協(xié)處理器可以支持另外的數(shù)據(jù)類型,包括一套浮點數(shù)據(jù)類型,ARM的核并沒有明確的支持。
2 存儲器組織
圖3-1所示為存儲器組織。
ARM這的地址的低三下四位必須為00,半字地址的最低位為0。字的內(nèi)容在存儲器中的存放通常有兩種方式,即小端(little-endian)和大端(big-endian),這兩種方式的不同在于最低位字節(jié)的地址是否在最高位字節(jié)的地址之前。小端方式每個字的低位字節(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
?。╝)小端存儲器組織 (b)大端存儲器組織
圖3-1 存儲器組織
3 ARM指令特點
1.每條指令的多功能
ARM指令一個重要的特點是它所有的指令都帶有條件,例如用戶可以測試某個寄存器的什但是直到下次使用同一條件進(jìn)行測試時,才能有條件的執(zhí)行這些指令。ARM指令另一個重要的特點是具有靈活的第2操作數(shù),既可以是立即數(shù),也可以是邏輯運算數(shù),使得ARM指令可以在讀取數(shù)值的同時進(jìn)行算術(shù)和移位操作。它可以在幾種模式下操作,包括通過使用SWI(軟件中斷)指令從用戶模式進(jìn)入系統(tǒng)模式。
2. 協(xié)處理器的作用
ARM內(nèi)核可以提供協(xié)處理器指令接口,通過擴展協(xié)處理器完成復(fù)雜的功能,因此,ARM指令還包含了多條協(xié)處理器接口,使用多達(dá)16個協(xié)處理器;允許將其他處理器能過協(xié)處理器接口進(jìn)行耦合;還包括幾種內(nèi)豐管理單元的變種;包括簡單的內(nèi)存保護(hù)到復(fù)雜的內(nèi)存保護(hù)到復(fù)雜的頁面層次。例如,管理存儲部件MMU就是ARM內(nèi)核通過協(xié)處理器CP15實現(xiàn)對內(nèi)存的管理。
3. Thumb指令
ARM有兩種指令集:16位Thumb指令集和32位ARN指令集。使用16位的存儲器可以降低成本,在這種情況下,Thumb指令集的整體執(zhí)行速度比32位指令集快,而且提高了代碼密度,所以一般用Thumb編譯器將C語言程序編譯成16位的代碼。處理器一開始總在arm狀態(tài),可使用BX指令轉(zhuǎn)換到Thumb狀態(tài)。
4. 具有RISC指令的特點
由于ARM指令屬于RISC指令,所以具有RISC指令的特點,指令少,且等長,便于充分利用流水線技術(shù);使用多寄存器,且多為簡單的Load與Store指令(從內(nèi)存中讀取某個值,執(zhí)行完操作后再將其放回內(nèi)存)。
5. 立即數(shù)和直接地址
由于指令統(tǒng)一為32位,無法在1條指令中存放32位立即數(shù)。一般立即數(shù)為5~12位。采用一些特殊的方法,使它能處理立即數(shù)。
同理,直接(或相對)地址一般為24位,但由于指令地址的低2位為00,故尋地范圍為±226,相對地址為±225。
3.2 ARM指令系統(tǒng)
3.2.1 ARM指令的尋址方式
每條ARM指令都是32位指令,在大多數(shù)情況下,可以有3個操作數(shù),其中第1個操作數(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相對尋址
例:
B rel ;(PC)+rel→PC
另外,每條ARM指令中還可以有第2條和第3條操作數(shù),它們采用復(fù)合尋址方式,ARM的復(fù)合尋址方式有5種。
1 第2操作數(shù)的尋址方式
ARM運算指令和某些數(shù)據(jù)傳送指令除了目的操作數(shù)和第1個操作數(shù)(它們?yōu)榧拇嫫鲗ぶ罚┩猓€具有第2操作數(shù)。該第2操作數(shù)具有以下尋址方式:
(1)立即尋址(#immediate_8*r*2)
由8位立即數(shù)和4位移位位r決定。R指定左移rⅹ2位,r=0~15,實際上可移位0,2,4,6,···,28,30。例如:實際的立即數(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ì)請見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 字和無符號字節(jié)尋址方式
ARM中的取數(shù)指令的源操作數(shù)和存數(shù)指令的目的操作數(shù)采用帶偏移量的變址方式,可以表示為基址+變址尋址。有效地址寄存器的內(nèi)容加上偏移量的值。對于字和無符號字節(jié),尋址方式通??梢园?種:寄存器間接尋址,前變址偏移尋址和后變址偏移尋址。帶偏移量的變址包括常數(shù)蔌寄存器值。
(1)存器間接尋址)[Rn])
例:
LDR R0,[R1] ;((R1))→R0
STR R0,[R1] ;(R0)→(R1)
?。?)前變址偏移尋址([Rn,偏移量]{!})
在數(shù)據(jù)傳送之前,瘵偏移量加到Rn中。其結(jié)果作為傳送數(shù)據(jù)的存儲器地址。若使用后綴“!”,則結(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
③移位寄存器偏移
?。跼n, ±Rm,LSL #《immede_5》{!}
?。跼n, ±Rm,LSL #《immede_5》{!}
?。跼n, ±Rm,ASR #《immede_5》{!}
[Rn, ±Rm,ROR #《immede_5》{!}
?。跼n, ±Rm,RPX]{!}
例:
LDR R0,[R1,R2,LSL #2] ;((R1)+(R2)*4→R0
?。?)后變址偏聽偏信移尋址([Rn],偏移量)
Rn的值用作傳送數(shù)據(jù)的存儲器地址。在數(shù)據(jù)傳送后,偏移量加到Rn中,結(jié)果寫回到Rn。Rn不允許是R15。
該尋址方式又分為下列3種:
①立即數(shù)偏移[Rn],#±《immde_12》
例:
LDR R0,[R1],#4 ;((R1))→R0,(R1)+4→R1
?、诩拇嫫髌疲跼n],±Rm
例:
LDR R0,[R3],-R8 ;((R3))→R0,(R3)-(R8)→R3
③移位寄存器偏移
[Rn],±Rm,LSL#《immde_5》
[Rn],±Rm,LSR#《immde_5》
[Rn],±Rm,ASR#《immde_5》
?。跼n],±Rm,ROR#《immde_5》
?。跼n],±Rm,RPX
例:
LDR R0,[R3],R8,LSL#2 ;((R3))→R0,(R3)+(R8)*4→R3
3 半字和有符號字節(jié)尋址方式
ARM中的半字和有符號字節(jié)取數(shù)和存數(shù)指令的尋址方式與字和無符號字節(jié)的尋址方式略有不同。
?。?)寄存器間接尋址([Rn])
例:
LDR R0,[R1]
STR R0,[R1]
?。?)前變址偏移尋址([Rn,偏聽偏信移量]{!})
?。?)在數(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
?。?)后變址偏聽偏信移尋址(Rn),偏移量)
Rn的值用作傳送數(shù)據(jù)的存儲器地址。在數(shù)據(jù)傳送后,偏移量加到Rn中,結(jié)果寫回到R n。Rn不允許是R15。
該尋址方式又分為下列3種:
?、倭⒓磾?shù)偏移[Rn],#±immed_8》
例:
LDR R0,[R3],-R8 ;((R5))→R0,(R5)+22→R5
?、诩拇嫫髌疲跼n],±Rm
例:
STR R0,[R3],-R8 ;(R0)→(R3),(R3)-(R8)→R3
4 塊尋址
ARM對堆棧的使用一般用多寄存器傳送指令,是一種有效的保存處理器狀態(tài)格多字節(jié)傳送的有效方式。ARM硬件中的堆棧分為以下4種:]
?、贊M向上生長型:堆棧按高地址方向生長,當(dāng)前堆棧指針指向一個有效值;
②空向上生長型:堆棧按高地址方向生長,當(dāng)前堆棧指針指向一個空值;
?、蹪M向下生長型:堆棧按低地址方向生長,當(dāng)前堆棧指針指向一個有效值;
④空向下生長型:堆棧按低地址方向生長,當(dāng)前指針指向一個空值。
圖3-2說明了4條帶不同變量和多字節(jié)傳送前后和內(nèi)存變化,以及基寄存器的變化情況。指令執(zhí)行前的基寄存器是R9,指令執(zhí)行后的基寄存器是R9’。
常見多字節(jié)傳送指令如表3-1所示。
表3-1內(nèi)FD|ED|FA|EA后綴只在堆棧時使用。F和E、分別代表指針指向為滿或空。A和D分別表示堆棧是否向上或向下生長。例如:堆棧如果是向上生長,STM指令向上存放,LDM指令向下讀取。IA、IB、DA、DB后綴在一般數(shù)據(jù)傳送時使用。注意:LDMED與LDMIB是同一條指令(下同)。
圖3-2多寄存器傳送示意
表3-1常見多字節(jié)傳送指令
?。?協(xié)處理器尋址方式
ARM協(xié)處理器尋址方式包括以下4種方式:
?。ǎ保┘拇嫫髦苯訉ぶ罚ǎ跼n]);
(2)前普址偏移尋址([Rn,#±《immed_8*4》]{!});
(3)后變址偏移尋址([Rn],#±《immed_8*4》);
?。ǎ矗?a target="_blank">參數(shù)無偏移尋址([Rn],{8-bit copro.Option}。
3.2.2 ARM指令的條件執(zhí)行
每條ARM指令都是有條件執(zhí)行,包括特權(quán)調(diào)用和協(xié)處理器指令,可根據(jù)執(zhí)行結(jié)果來選擇是否更新條件碼。若要更新條件碼,則指令中須包含后綴“S”。條件占32位指令的高4位。
一些指令(如CMP、CMN、TST、和TEQ不需要后綴“S”。它們唯一的功能就是更新條件標(biāo)志,且始終更新條件碼。更新之前保持不變。沒執(zhí)行的條件指令對標(biāo)志沒影響,一些指令只更新部分標(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中符號“*”的說明:HS、LO、HI、LS這4個條件碼指的是無符號數(shù),GE、LT、GT、LE這4個條件碼指的是符號數(shù)。
3.2.3 Load/Store類指令
1. 單字和無符號字節(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
??;無“!”,Rn不變
前變址指的是在數(shù)據(jù)傳送之前,將偏移量加到Rn中,其結(jié)果作為傳送數(shù)據(jù)的存儲地址。若使用后綴“!”,則結(jié)果寫回到Rn中。Rn不允許是Rn15。
(3) 程序相對偏移(program-relative)
LDR|STR{《條件碼》}Rd,Ladel ;(Label) →Rd
程序相對偏移指的是由PC計算偏移量,并將PC生成指令。不能使用后綴“!”?!埃蹋模摇d,Label”等價為“LDR Rd,[Rn],offset”等價為“((Rn))→Rd,(Rn)+offset→Rn]”
?。?) 后變址(post-indexed offset)
LDR|STR{《條件碼》{B}{T} Rd,[Rn],《offset》
后變址指的是將Rn的值用作傳送數(shù)據(jù)的存儲器地址,數(shù)據(jù)傳送后,偏移量加到Rn中,結(jié)果寫回到Rn。Rn不允許是R15?!癓DR Rd,[Rn],offset”等價為“((Rn))→,(Rn)+offset→Rn”。
其中:
B 可選后綴。若有B,則傳送Rd的最低有效字節(jié)。若操作碼是LDR,則將Rd的其他字節(jié)清零。
T 可選后綴。若有T,那么即使處理器在特權(quán)模式下,存儲系統(tǒng)也將訪問看成是處理器在用戶模式下。T在用戶模式下無效,不能與前變址偏移一起使用T。
Rd ARM寄存器。
Rn 存儲器的基址寄存器,若指令是帶寫回(write back)的前變址(后綴為“!”)或后變址,或使用T后綴,則不允許Rn與Rd相同。
Offset Rn上的偏移量。
Label 程序相對偏移表達(dá)式,必須在當(dāng)前指令的前指令的±4KB內(nèi)。
??! 可選后綴。若有“!”則將包含偏移量的地址寫回到Rn。若Rn是R15,則不能使用后綴“!”。
注釋:
?。?) offset 說明
前變址和后變址格式中的offset可以是2種形式之一:
?。?) exression
其含義是符號表達(dá)式,通常是數(shù)字整數(shù)常量,取值在-4095~+4095之間。
(3) ±Rm{.shift}
其中:
± 可選負(fù)號。若有符號“-”,則從Rn中減去偏移量。否則,將偏移量加到Rn中。
Rm 內(nèi)含偏移量的寄存器。Rm不允許是R15。
Shift Rm的可選移位方法??梢允茿SR、LSL、LSR、ROR、RRX的任何一種。詳細(xì)說明見ARM數(shù)據(jù)處理類指令的第二操作數(shù)。
?。?) 字地址對準(zhǔn)
大多數(shù)情況下,必須保證用于32位傳送的地址是32位對準(zhǔn)的。
若系統(tǒng)中有協(xié)處理器(CP15),則允許對準(zhǔn)檢查,若允許對準(zhǔn)檢查,則非字對準(zhǔn)的32位傳送會引起對準(zhǔn)異常。若系統(tǒng)中沒有系統(tǒng)協(xié)處理品(CP15),或禁止對準(zhǔn)檢查,則有:
對于STR,將指定的地址取成4的倍數(shù)。
對于LDR,則
l將指定的地址取成4的倍數(shù)。
l由結(jié)果地址讀取4個字節(jié)的數(shù)據(jù)。
l依據(jù)地址的位[1:0],將讀取的數(shù)據(jù)循環(huán)右移1、2或3個字節(jié)。
對于小端存儲系統(tǒng),這使尋址的字節(jié)占用寄存器的最低有效字節(jié)。
對于大端存儲系統(tǒng),這使尋址的字節(jié)占用:
-位[31:24],若地址的位[0]為0;
-位[15:8],若地址的位[0]為1。
?。?) 使用R15讀取
使用R15(程序計數(shù)器)讀取會引起處理器轉(zhuǎn)移到所讀取地址的指令。
對于讀取值的位[1:0],有:
l對于ARM體系結(jié)構(gòu)v3及以下版本,忽略位[1:0]。
l對于ARM體系結(jié)構(gòu)v4及以上版本的非T變量,位[1:0]為0。
l對于ARM體系結(jié)構(gòu)v5及以上版本的T變量,則有
-對于讀取到R15的值,其位[1:0]不允許是ob10;
-對于讀取到R15的值的位[0]置位,則處理器轉(zhuǎn)到Thumb狀態(tài)。
當(dāng)使用R15讀取時,不能使用后綴“B”或“T”。
?。?) 使用R15存儲
通常應(yīng)盡量避免使用R15存儲。
若使用R15存儲,則存儲的值是當(dāng)前指令的地址加上實現(xiàn)所定義的常量。對于特寫的處理器這個常量始終不變。
例 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時((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),存儲R0的最低有效字節(jié),R3和R8不變
STR R%,[R7],#-8 ;讀取一個字,該字位于標(biāo)號loacaldata所在地址
2. 半字和有符號字節(jié)Load/store類指令
功能:提供ARM寄存器和內(nèi)存之間半字(16位)和有符號字節(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》]{!}
?。?) 程序相對偏移(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 對有符號半字(僅LDR);
H 對無符號半字;
SB 對有符號字節(jié)(僅LDR)。
Label 程序相對偏移表達(dá)式。必須是在當(dāng)前指令的±255字節(jié)范圍內(nèi)。
Offset 加在Rn上的偏移量。含義見注釋。
Rn和“!”同前面第1條(LDR和STR字和無符號字節(jié))。
注釋:
(1) offset說明
前變址和后變址格式中的offset可以是下兩種形式之一:
?、賓xpression含義同前一條指令,取值在-255~+255范圍之間。
②±Rm含義同前一條指令。
?。?) 半字傳送的地址對準(zhǔn)
半字傳送的地址必須是偶數(shù)。
若系統(tǒng)有系統(tǒng)協(xié)處理器(CP15),則可允許對準(zhǔn)檢查。若允許對準(zhǔn)檢查,則非對準(zhǔn)的16位傳送會引起對準(zhǔn)異常。若系統(tǒng)沒有系統(tǒng)協(xié)處理器(CP15)或禁止對準(zhǔn)檢查,則有
l非半字對準(zhǔn)的16位讀取將使Rd內(nèi)容不可靠;
l非半字對準(zhǔn)的16位存儲將使在address和(address-1)的2個字節(jié)不可靠。
(3) 不能將半字或字節(jié)讀取到R15。
例 1:
LDREQSH R11,[R6] ;(有條件地)R11←[R6],讀取16位半字,有符號擴展到32位
LDH R1,[R0,#22] ;R1←[R0+22],讀取16位半字,零擴展到32位
STR R4,[R0+R1] ;存儲最低的有效半字到R0+R1地址開始的兩個字節(jié),地址寫回到
;R0
LDRSB R6,constf ;讀取位于標(biāo)號constf地址中的字節(jié),有符號擴展
例 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 ;取得有符號半字?jǐn)?shù),擴展為字
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) 程序相對偏移(pregram-relatve)
LDR|STR{《條件碼》}D Rd,LABEL
(4) 后變地址格式(post-indexed offset)
LDR|STR{《條件碼式》}D Rd,[Rn],《offset》
其中:
Rd 讀取或指令寄存器其中的一個,另一個是R(d+1).Rd必須是偶數(shù)寄存器,且不是R14.
Rn 除非指令為零移,或不帶寫回的前索引,否則R不允許是Rd和R(d+1)相同。
Offset 加在Rn上的偏移量。含義同3.2.3節(jié)第1條指令。
Label 程序相對偏移表達(dá)式.Label必須是在當(dāng)前指令的±255字節(jié)范圍內(nèi)。
??! 可選后綴。若有”!”,則包含偏移量的最后地址寫回到Rn.
注釋:
對于雙字節(jié)傳送,地址必須是8的倍數(shù)。若系統(tǒng)有系統(tǒng)協(xié)處理器,可允許對準(zhǔn)檢查。若允許對準(zhǔn)檢查,慢非雙字準(zhǔn)的64位傳送將引起對準(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類指令
功能:讀取和存儲多個寄存器,可以傳送R0~R15的任何組合。
格式:
?。?) 標(biāo)準(zhǔn)格式
LDR|STM{《條件碼》}《mode》Rn{!}《寄存器》
?。?) 非用戶模式下,用下面可以同時把當(dāng)前的SPSR寫入CPSR中,轉(zhuǎn)向用戶模式,寄存器組飲包含PC.
LDM{《條件碼》}《mode》Rn{!},《寄存器組+PC》^
?。?) 非用戶模式下,用下面格式可以實現(xiàn)訪問用戶模式的寄存器,但寄存器組不包含PC.
LDM|STM{《條件碼》}《mode》Rn,《寄存器組-PC》^
其中:
mode IA、IB、DA、DB、FD、ED、FA、EA之一。
Rn 基址寄存器,裝有傳送數(shù)據(jù)的初始地址。Rn是不允許是R15。
! 可選后綴。若有“!”,則結(jié)果地址寫回到Rn。
Reglist讀取或存儲的寄存器列表,包含在括號中,它也可包含寄存器的范圍。若包含多于1個寄存器列表或包含寄存器范圍,則必須用逗號分開。
^ 可選后綴,不允許用戶模式或系統(tǒng)模式下使用。它有兩個目的:
l操作碼是LDM且reglist中飽包含PC(R15),那么出除了正常的多寄存器傳送外,將SPSR也拷貝到CPSR中。這用于從異常處理返回,僅在異常模式下使用。
l數(shù)據(jù)傳入或傳出的是用戶模式的寄存器,而不是當(dāng)前模式的寄存器。
注意:對于LDM指令,如包含PC,位0=1時,轉(zhuǎn)至Thumb狀態(tài)。寄存器組中一般不應(yīng)有Rn,它至少有1個寄存器。FD、ED、FA、DA用于堆棧操作;IA、IB、DA、DB用于一般的數(shù)據(jù)傳送。
注釋:
?。ǎ保┓亲謱?zhǔn)地址
這些指令忽略地址的位[1:0]。在帶有系統(tǒng)協(xié)處理器的系統(tǒng)中,若對準(zhǔn)檢查使能,則這2位的非零值將引起對準(zhǔn)異常。
?。ǎ玻┳x取到R15
到R15(程序計數(shù)器)的讀取將引起處理器轉(zhuǎn)移到讀取地址處的指令。在ARM體系結(jié)構(gòu)v5及以上版本的T變量中若讀取的位[0]置位,則到R15的讀取將導(dǎo)致處理器切換到執(zhí)行Thumb指令。
?。ǎ常懟氐拇?取基址寄存器
如果Rn包含在寄存器列表中,且用后綴“!”,指明要寫回(write back),那么:
l若操作碼是STM,縣城Rn是寄存器列表中數(shù)字最小的寄存器,則將初值保存。
lRn的讀取和儲存值不可預(yù)知。
例1:若保存3個工作寄存器狀態(tài)和返回地址:
STMFD R13!,{R0-R2,R14}
若恢復(fù)3個工作寄存器狀態(tài)和返回地址:
LDMFD R13!,{R0-R2,R14}
例2:
LDMFD R8,{R0,R2,R9} ;((R8))→R0
?。唬ǎ≧8)+4)→R2
?。唬ǎ≧8)+8)→R9
STMDB R1!,{R3-R6,R11,R12} ;(R3)→R1-4
?。唬≧4)→R1-8
??;(R5)→R1-12
;(R6)→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ù)讀?。≒LD,PreLoad),使用PLD指示存儲系統(tǒng)從后面幾條指令所指定的存儲器地址讀取,存儲系統(tǒng)可使用這種方法加速以后的存儲器訪問。
格式:
PLD[Rn,{offset}]
其中:
Rn 存儲器的基址寄存器。
Offset 加在Rn上的偏移量。含義同3。2。3節(jié)第1條指令。
注釋:
PLD指令適用于ARM v5TE指令及以上版本。
例:
PLD [R9,#-2481]
PLD [R0,#av*4] ;av*4必須在匯編時求值,范圍為-4095~4095內(nèi)的整數(shù)
PLD [R5,r8,Lsl#2]
6. 內(nèi)存和寄存器交換類指令
功能:用一條指令實現(xiàn)在寄存器和存儲器之間交換數(shù)據(jù)。
格式:
SWP{《條件碼》}{B} Rd,Rm,[Rn] ;((Rn))→Rd,Rm→Rn
;n≠m,d
其中:
B 可選后綴。若有B,則交換字節(jié);否則,交換32位字。
Rd ARM寄存器。數(shù)據(jù)從存儲器讀取到Rd。
Rm ARM寄存器。Rm的數(shù)據(jù)存儲到存儲器。Rm可以與Rd相同。Rn必須與Rd和Rm不同。
注釋:
對非字對準(zhǔn)地址的處理同LDR和STR指令。
例:
ADR R0,SEMAPHORE
SWPB R1,R1,[R0] ;交換字節(jié)
3.2.4 ARM數(shù)據(jù)處理類指令
大多數(shù)ARM通用數(shù)據(jù)處理有一個靈活的第2操作數(shù)(flexi second operand)。在每一個指令的格式中以“operand2”表示。
第2條操作數(shù)有如下2種可能的格式:
?。?)#immed_8r
常量的表達(dá)式。常量必須對應(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 存儲第2操作數(shù)ARM寄存器。可用各種方法對寄存器中的位圖進(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ì)說明如下:
?、?ASR
若將Rm中的內(nèi)容看作是有符號的補碼整數(shù),那么算術(shù)右移(ASR,Arithmetic Shift Right)n位,即Rm中的內(nèi)容除以 。將原來的位拷貝到寄存器左邊的n位中(即空出的最高補符號位),見圖3-3(a)。
?、?LSR和LSL
若將Rm中內(nèi)容看作是無符號整數(shù),則邏輯右移(LSR,Logical Shift Right)n位,即Rm中的內(nèi)容除以 ,寄存器左邊的n位置0,見圖3-3(b)。
若將Rm中內(nèi)容看作是無符號整數(shù),則將邏輯左移(LSR,Logical Shift Left)n位,即Rm四的內(nèi)容乘以 ,可能會出現(xiàn)溢出且無警告,寄存器右邊的n 位置0,見圖3-3(b)。
?、?ROR
循環(huán)右移(ROR,Rotate Right)n位,把寄存器內(nèi)容循環(huán)右移,見圖3-3(c)。
?、?RRX
若將Rm中內(nèi)容看作是無符號整數(shù),則帶進(jìn)位右環(huán)移n位,寄存器左邊的n位置0,見圖3-3(d)。
圖3-3移位操作過程
1 數(shù)據(jù)運算類指令
功能:完成數(shù)據(jù)在寄存器中的運算,這些運算包括32位數(shù)據(jù)的算術(shù)、位操作,其中某一個操作數(shù)可以經(jīng)過移位或循環(huá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 存儲第1操作數(shù)的ARM寄存器。
Operand 第2操作數(shù)。詳細(xì)說明請見3.2.4節(jié)第2操作數(shù)說明。
ARM的數(shù)據(jù)運算類指令用法如表3-3所示。
表3-3 ARM運算類指令
注釋:
?。?) 條件碼標(biāo)志
若指定S,那么ADD、SUB、RSB、ADC、SBC、RSC指令根據(jù)結(jié)果更新標(biāo)志N、Z、C和V。CMP、CMN、TST和TEQ指令不需S。注意:減法(含比較)夠減時,C=1。而AND、OPR、EOP、BIC、MOV和MVN指令將:①根據(jù)結(jié)果更新標(biāo)志N和Z;②計算Operand2時更新標(biāo)志C;③不影響V標(biāo)志。
?。?) R15的使用
ADD、SUB、RSB、ADC、SBC、RSC、AND、ORR、EOR、BIC、MOV和MVN指令將R15作為Rn使用,那么使用的值是指令的地址加8。
若將用R15作為Rd,則
l執(zhí)行轉(zhuǎn)移到結(jié)果對應(yīng)的地址。
l若后綴“S”,則將當(dāng)前模式的SPSR拷貝到CPSR??梢允褂眠@點從異常返回。
在有寄存器控制移位的任何數(shù)據(jù)處理指令中,不能將R15作為Rd或任何操作數(shù)來使用。
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)零計數(shù)指令
功能:CLZ(Count Leading Zeros)指令對Rm中值的高位(leading zeros)個數(shù)進(jìn)行計數(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 乘法指令
格式:
?。?) MUL{《條件碼》}{S},Rd,Rm,Rs
?。?) 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é)果寄存器。對于UMLAL和SMLAL,這兩個寄存器用于保存累加值。
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的任何一個。任何Rd、Rm、Rs或Rn可用相同的寄存器。
?。?) SMULW《y》{條件碼}Rd,Rm,Rs,Rn
其中:
《y》、Rd、Rm、Rs和Rn含義同SMUL《x》《y》指令。
R15不能用作Rd、Rm、Rs或Rn的任何一個。任何Rd、Rm、Rs或Rn可用相同的寄存器。
?。?) SMULW《y》{條件碼}RdLo,RdHi,Rm,Rs
其中:
《x》《y》含義同SMULxy指令。
RdHi,RdLo 結(jié)果寄存器。它們也存儲累加值。
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)也不會清除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增強指令,完成飽和加、飽和減,飽和乘2加、飽和乘2減4種飽和運算功能。
格式:
《操作碼》{條件碼}Rd,Rm,Rn
《操作碼》包括:QADD、QSUB、QDADD和QDSUB指令。
其中:
Rd 結(jié)果寄存器。
Rm,Rn 操作寄存器。
注釋:
飽和運算是DSP指令所特有的功能,對加/減法指令的結(jié)果做了如下修改:
?。?) 如果加/減法指令的結(jié)果在- ~ -1之間,飽和運算的結(jié)果取加/減法指令的結(jié)果。
(2) 如果加/減法指令的結(jié)果大于 -1,飽和運算的結(jié)果取最終結(jié)果為 -1。
?。?) 如果加/減法指令結(jié)果小于- ,飽和運算的結(jié)果取最終結(jié)果為時尚- 。
QDADD和QDSUB指令計算SAT(Rm+SAT(Rn*2)),飽和可發(fā)生在加倍操作,加法上,或兩咱情況下同時發(fā)生。或飽和僅發(fā)生在加倍操作上,則標(biāo)志Q置位,但最后結(jié)果是不飽和的。SAT意為飽和運算。
這些指令不影響標(biāo)志N、Z、C和V。若出現(xiàn)飽和,則置位Q標(biāo)志??墒褂肕RS指令來讀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中完成連接作用,通常用來完成子程序的調(diào)用。
轉(zhuǎn)移地址通常由24位有符號數(shù)組成,由于指令地址的代位為00,故可進(jìn)行2位的左移運算,因此總的偏移量達(dá)到±32M。
格式:
B{L}{《條件碼》}《Label》
其中:
Label 程序相對偏移表達(dá)式。
注釋:
BL(Branch and Link)指令將下一條指令的地址拷貝到R14(LR,鏈接寄存器)并引起處理器轉(zhuǎn)移到Label。BL指令(L=1),等價于先把(PC)→R14,再(PC)+offset→PC.
機器級的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
… ;返回點
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指令用來支持者Thumb指令集,可以全處理器由ARM指令轉(zhuǎn)向Thumb指令或者由于某種原因Thumb指令返回到執(zhí)行ARM指令。
格式:
(1)B{L}X{《條件碼》}寄存器Rm
?。ǎ玻〣LX《Label》
其中:
RM 含有轉(zhuǎn)移地址的寄存器。Rm的位[0]不用來作為地址的一部分。若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中偏移地址量的計算與B或BL指令相同。
BLX指令有如下用法:
l將下一條指令的地址拷貝到R14中(LR,鏈接寄存器)。
l轉(zhuǎn)移到Label或Rm中的地址。
l若下面的兩條中的任何一條成立,則指令集切換到Thumb,即
-Rm的位[0]為1;
-使用“BLX Label“形式。
機器級的“BLX Label“指令不能轉(zhuǎn)移當(dāng)前指令±32MB范圍之外的地址BLX指令格式1可以是條件或者無條件執(zhí)行,而指令格式2是無條件執(zhí)行。
例1:無條件轉(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é)處理器與存儲器之間的數(shù)據(jù)傳送、協(xié)處理器與CPU寄存器之間的數(shù)據(jù)傳送。這些指令依賴于使用特寫的協(xié)處理器。協(xié)處理器設(shè)計者可以自由地按需要設(shè)計處理器的功能,而且這些指令通常借助于匯編器。
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è)計者提供額外的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完成
?。徊僮?(子操作2),然后將結(jié)果放在C1中
2 LDC和STC指令
功能:在存儲器和協(xié)處理器之間傳送數(shù)據(jù)。
格式:
(1) 零偏移格式
LDC|STC{《條件碼》}{L}《CP#》,CRd,[Rn]
?。?) 前變址格式
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 可選后綴,指明是長整數(shù)傳送。
CP# 指令操作的協(xié)處理器名。標(biāo)準(zhǔn)名為pn,其中n為0~15范圍內(nèi)的整數(shù)。
CPd 用于讀取或存儲的協(xié)處理器寄存器。
Rn 存儲器基址寄存器。若指定R15,則使用的值是當(dāng)前指令地址加8。
Offset 偏移量,其值必須為4的整倍數(shù),范圍在0~1020之間。
注釋:
LDC2和STCC2指令設(shè)置條件碼條件碼為b1111,為協(xié)處理器設(shè)計者提供額外的opcode空間。LDC2和STC2指令適用于ARM v5指令系統(tǒng)及以上版本。注意:LDC2和STC2始終是無條件的。
例1:
LDC p6,CR1,[R4] ;將存儲器中的內(nèi)容取至協(xié)處理器6
??;寄存器CR1中R4為所以內(nèi)容地址
例2:
LDC p6,CR4,[R2,4] ;將存儲器中的內(nèi)容取至協(xié)處理器6
??;寄存器CR4中R2+4為所以內(nèi)容地址
例3:
STC p8,CR8,[R2,#4]! ;將協(xié)處理器8寄存器CR8中的內(nèi)容存
;至存儲器中R2+4為所存內(nèi)容的地址
??;然后,R2=R2+4
例4:
STC p6,CR9,[R2],#-16 ;將協(xié)處理器6寄存器CR9中的內(nèi)容存
?。恢链鎯ζ髦蠷2為所存內(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è)計者提供額外的操作碼字段。MRC2和MCR2指令適用于ARM v5指令系統(tǒng)及以上版本。注意:MRC2和MCR2始終是無條件的。
例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中完成
?。徊僮?(子操作6,然后將結(jié)果傳到協(xié)
??;處理器14的寄存器C12中
4 MCRR和MRRC指令
功能:在2個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雜項指令
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)模式下,一定不能試圖訪問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:擴展域屏蔽字段(PSR中的第8位到第15位);
lS:狀態(tài)域屏蔽字段(PSR中的第16位到第32位);
lF:標(biāo)志域屏蔽字段(PSR中的第24位到第31位)。
immed_8r 值數(shù)字常量的表達(dá)式。常量必須對應(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指令用來執(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:通過SWI指令輸出字符串
…
BL STROUT ;輸出如下信息
= “Hello World”,&0a,&0d,0
… ;返回
STROUT LDRB R0,R[14],#1 ;得到字符
CMP R0,#0 ;檢查結(jié)束標(biāo)記
SWINE SWI_WriteC ;如果沒有結(jié)束,則繼續(xù)
BNE STROUT ;…循環(huán)
ADD R14,#3 ;字對齊
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í)行時中斷正常指令,進(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)用指令,也會轉(zhuǎn)移到Thumb指令中去。如果例程處理完畢,也將返回ARM指令中。
必須明確的是Thumb指令系統(tǒng)必須包括ARM代碼,至少是初始化和例程入口部分。
Thumb指令集是ARM指令集的子集,Thumb只使用有限的ARM寄存器。Thumb指令一般可以完全訪問通用寄存器R0~R7(稱為低寄存器),R13用作堆棧指針,R14用作鏈接寄存器,R15用作PC。Thumb中的一些指令可以訪問其余的寄存器如R8~R15(稱為高寄存器),算術(shù)運算和邏輯運算指令可以訪問CPS2中的標(biāo)志位。
大部分的Thumb 指令與ARM指令類似,不過在寄存器、立即數(shù)、尋址等方面會有些差異,Thumb和ARM指令性計劃集的區(qū)別一般有以下幾點:
l轉(zhuǎn)移指令;
l數(shù)據(jù)傳送指令;
l單寄存器Load和Store指令;
l多寄存器Load和Store指令。
Thumb指令集沒有協(xié)處理器指令、信號量(samaphore)指令以及訪問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)。
程序相對轉(zhuǎn)移,特別是條件轉(zhuǎn)移與在ARM狀態(tài)下相比,在范圍上有更多的限制,轉(zhuǎn)向子程序只能是無條件轉(zhuǎn)移。
?。?) 數(shù)據(jù)處理指令
這些指令對通用寄存器進(jìn)行操作,在許多情況下,操作的結(jié)果必須放入其中一個操作數(shù)寄存器中,而不是第3個寄存器中。數(shù)據(jù)處理操作比ARM狀態(tài)更少,訪問寄存器R8~R15受到一定限制。
MOV或ADD指令可訪問寄存器R8~R15,數(shù)據(jù)處理指令總是更新CPS2中的ALU狀態(tài)標(biāo)志。訪問寄存器R8~R15的Thumb數(shù)據(jù)處理指令不能更新標(biāo)志。
?。?) 單寄存器Load和Store指令
這些指令從存儲器讀取1個寄存器值,或把1個寄存器值存儲到存儲器。在Thumb狀態(tài)下,這些指令只能訪問寄存器R0~R7。
?。?) 多寄存器Load和Store指令
?。蹋模秃停樱裕蛯⑷魏畏秶鸀椋遥啊遥返募拇嫫髯蛹瘡拇鎯ζ髯x取以及存儲到存儲中。
?。校眨樱群停校希兄噶钍褂枚褩V羔槪≧13)作為基址實現(xiàn)滿遞減堆棧。除可傳送R0~R7外,PUSH還可以用于存儲連接寄存器,POP可以用于讀取程序指針。
Tuhmb指令主要有以下幾類指令組成:Tuhmb Load/Store類指令;Thumb數(shù)據(jù)運算類指令;Thumb轉(zhuǎn)移類指令,以及軟件中斷指令。
3.3.1 Thumb Load/Store類指令
1 Thumb單寄存器Load/Store指令
Thumb單寄存器傳送類指令是ARM單寄存器傳送類指令的一個子集,和ARM有相同的指令格式。
Thumb單寄存器傳送指令分以下4種:
(1) LDR和STR—立即數(shù)偏移
功能:讀取寄存器和存儲寄存器。寄存器的地址用一個寄存器的數(shù)偏移量指明,立即數(shù)偏移的半字和字節(jié)讀取是無符號的。
格式:
?。疾僮鞔a>Rd,[Rn,《#immed_5*N》]
?。疾僮鞔a>包括:LDR,LDRB,STR,STRH和STRH指令
其中:
H 指明無符號半字傳送。
B 指明無符號字節(jié)傳送
RD 讀取和存儲寄存器。Rd必須在R0—R7范圍內(nèi)
RN 基址寄存器.Rn必須在R0—R7范圍內(nèi)
Immed_5*N 偏移量。Immed_5是一個表達(dá)式,其中值在0--31范圍內(nèi),在匯編時結(jié)果是的N倍數(shù)。
對字節(jié)傳送,N=1
對半字傳送,N=2az
對字傳送, N=4
注釋:
字傳送的地址必須可被4整除,半字傳送的地址必須可被2整除。
若系統(tǒng)中有系統(tǒng)協(xié)處理器(CP15),則可允許對準(zhǔn)檢查。若允許對準(zhǔn)檢查,則非對準(zhǔn)的傳送會引起對準(zhǔn)異常
若系統(tǒng)沒有協(xié)處理系統(tǒng)器(CP15)或禁止對準(zhǔn)檢查,則:
非對準(zhǔn)讀取使Rd不可靠
非對準(zhǔn)存使存儲器的2個或4個字節(jié)不可靠。對半字存儲,不可靠的存儲器位置是address AND NOT 0x1; 于字存儲器,則是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---寄存器偏移
功能:讀取寄存器和存儲寄存器。存儲器的地址用一個寄存器的基于寄存器偏移指明存儲器地址。
格式:
《操作碼》Rd,[Rn,Rm]
《操作碼》是下列情況之一:
讀取寄存器,4字節(jié)字
存儲寄存器,2字節(jié)字
讀取寄存器,2字節(jié)無符號半字
讀取寄存器,2字節(jié)字有符號半字,有符號位擴展(即高位字節(jié)與符號字節(jié)相同)
存儲寄存器,2字節(jié)半字
讀取寄存器,無符號半字
讀取寄存器,有符號半字,有符號位擴展(即高位字節(jié)與符號位相同)
存儲寄存器,字節(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相對偏移
功能:讀取寄存器和存儲器。存儲器中的地址用中內(nèi)容的立即數(shù)偏移指明。字節(jié)碼結(jié)構(gòu):
格式:
LDR Rd,[PC,#immed_8*4]
LDR Rd,Label
其中:
immed_8*4偏移量。它是一個表達(dá)式,取值(在匯編時)為4的整數(shù)倍,范圍在0~1020內(nèi)。
Label 程序相對偏移表達(dá)式。必須在當(dāng)前指令之后且范圍內(nèi)。
注釋:
同3.3.1節(jié)第1條指令
例:+
LDR R2,[PC,#1016]; ((PC)+1026)---R2
LDR R5,localdata
?。?) LDR和STR---SP相對偏移
功能:讀取寄存器和存儲寄存器。存儲器的地址用中內(nèi)容的立即數(shù)偏移指明。
格式:LDR Rd,[SP,#immed_8*4]
STR Rd,[SP,#immed_8*4]
其中:
immed_8*4
偏移量。它是一個表達(dá)式,取值(在匯編時)為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和多個Store寄存器
格式:(1)LDMIA Rn!, 《Reglist》 (2)STMIA Rn!,《Reglist》
其中:
Reglist 低寄存器或低寄存范圍的,用逗號隔開的列表。列表中至少有一個寄存器。
Rn 目的寄存器,必須是低于寄存器
注釋:
?。?)寄存器以數(shù)字順序取或存儲。最低數(shù)字的寄存器在的初地址中。的值以中寄存器個數(shù)的4倍增加。
?。?)若在Rn寄存器列表中,則
對于LDMIA指令,Rn的最終值是讀取的值,不是增加后的地址。
對于STMIA指令,Rn的終值有如以下兩種情況:
---若是寄存器列表中最低的寄存器,則的存儲值為初值;
---其他情況則不可預(yù)知。
例:
LDMIA R3!,(R0,R4); (R0)---(R3),(R4)---(R3)+4; (R3)+8---R3
STMIA R0!,(R3,R5,R7);((R0)--R3,((R0)+4)---R5,
?。唬ǎ≧0)+8)---R7,(R0)+12---R0
3 堆棧指令
功能:低寄存器和可選的LR進(jìn)棧,低寄存器和可選的PC出棧。
格式:POP {《REglist》{,PC}}
PUSH {《Reglist》{,LR}}
其中:Reglist
低寄存器或寄存器范圍的,用逗號隔開的列表。
注釋:
(1)Thumb堆棧是滿遞減堆棧,向下增長,且SP指向堆棧的最后入口。
?。?)寄存器以數(shù)字順序存儲在堆棧中。最低數(shù)字的寄存器其地址最低。
?。?)POP{Reglist}這條指令引起處理器轉(zhuǎn)移到從堆棧彈出給PC的地址,這通常是從子程序返回,其中LR在子程序開頭壓進(jìn)堆棧。
?。?)對于ARMv5T及以上的版本,則
若讀到PC中的值的位[1:0]是b00,則處理器變換到ARM狀態(tài)
位[1:0]不允許的值b10。
?。?)條件碼標(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ù)運算類指令
Thumb數(shù)據(jù)運算指令有以下8種:
1 ADD和SUM-----低寄存器
功能:2個寄存器的,內(nèi)容相加或相減,結(jié)果放到第3個寄存器中。
格式:《操作碼》Rd,Rn,Rm
《操作碼》包括:ADD,SUB指令。
其中:
Rd 目的寄存器。必須是低寄存器
Rn 第操作寄存器。必須是低寄存器
Rm 第2操作寄存器。必須是低寄存器。
注釋:這些指令更新標(biāo)志N,Z,C,V。
例:ADD R3,R1,R5。
2 ADD和SUB----小整數(shù)
功能:寄存器中的值加上或減去一個小整數(shù),結(jié)果放在另一個不同寄存器中。
格式:《操作碼》 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ù)
功能:寄存器中的值對于一個大事整數(shù)進(jìn)行ADD,SUB,MOV,CMP運算,結(jié)果放在另一個不同的寄存器中。
格式:
《操作碼》 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匯編時必取值范圍為—255~+255的整數(shù)
4 ADD,MOV,CMP----高或低寄存器
功能:將寄存器中值進(jì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 ; 等價于“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匯編時必須取值為范圍在---508~+508內(nèi)4的整數(shù)倍。
6 ADD---PC或SP相對偏移
功能:SP或PC值加上一立即相對數(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運算
功能:移位和循環(huán)移位操作。這些指令可使用寄存器中的值或立即數(shù)移位。
格式1:
《操作碼》Rd,Rn,《#immed_5》
其中:
《操作碼》是下列的任何一種:
ASR算術(shù)右移。將寄存器中的內(nèi)容看作補碼形式的有符號整數(shù)。將符號位移拷貝到空位。
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ù)移位量。它是一個取值為整數(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取值,并對其進(jìn)行移位,結(jié)果放回Rd中。
?。?)寄存器控制移位(格式2)
這些指令從Rd中取值,并對其進(jìn)行移位,結(jié)果放回Rd.只有Rs的最低的效數(shù)字節(jié)可用作移位量。
對于除ROR以外的所有指令,則有
若移位量為32,則Rd清零。最后移出的位保留在標(biāo)志C中。
若移位量大于32,則Rd和標(biāo)志C均被清零。
?。?)條件碼標(biāo)志
這些指令根據(jù)結(jié)果更新標(biāo)志N與Z,且不影響標(biāo)志V。對于標(biāo)志C,若移位量是零,則它不受影響,其他情況下,它包含源寄存器的最后移出位。
例:ASR R3,R5
LSR R0,R2,#6
LSR R%,R5,av; av的值必須在匯編時取成在1~32范圍內(nèi)的整數(shù)
LSL R0,R4,#0 ;除了不影響標(biāo)志C和V外,同“MOV R0,R4”
8 其他運算類指令
格式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ù)處理指令
助記符含義動作
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)位減法減法減法減法測試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,對標(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會使標(biāo)志C和V不可靠。在ARM v5及以后的版本中,MUL不影響標(biāo)志C和V。
注意:可用移位為0來使用LSL,實現(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 程序相對偏移表達(dá)式。通常是在同一代碼塊內(nèi)標(biāo)號。
若使用條件碼,則必須在當(dāng)前指令的—254~+254字節(jié)范圍內(nèi);
若指令是無條件,則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é)果為正溢出無溢出大于小于大于等于小于等于大于小于等于 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 程序相對轉(zhuǎn)移表達(dá)式。
注釋:
BL指令將下一條指令的地址拷貝到R14(LR鏈接寄存器),并引起處理器轉(zhuǎn)移到Label。機器級指令不能轉(zhuǎn)移到當(dāng)前正負(fù)4MB指令以外的地址。必要時,ARM鏈接器插入代碼(veneer)以允許更長的轉(zhuǎn)移。
BL指令實際上分為2條指令,1條指令H=0,它把11位偏移量左移12位,加上現(xiàn)行PC,寫入中R14(LR),另一條指令H=1,它把LR加上11位偏移量乘2寫入PC,同時把下一條指令寫入R14中。
BLX指令可用于:
拷貝下一條指令的地址到R14(LR鏈接寄存器)。
引起處理器轉(zhuǎn)移到Label或Rm存儲的地址
如果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存儲的地址。若Rm的位[0]置位,則指令集切換到Hhnmb狀態(tài)。
BLX指令用來在Thumb程序中調(diào)用ARM或者子程序,地址由Rm指定。從子程序返回,用BX R14指令。
例:
BX R5
BLX R6
3.3.4 Thumb軟件中斷和斷點指令
1 Thumb軟件中斷指令
功能:Thumb的SWI指令類似于ARM SWI指令。該指令執(zhí)行后的操作是:
(1)將下一條Thumb指令地址保存進(jìn)R14_svc。
?。?)PSR的內(nèi)容保存進(jìn)SPSR_svc;
?。?)禁止IRQ中斷,清除Thumb位,進(jìn)入SVC模式;
?。?)PC指向0x08。
返回指令恢復(fù)Thumb執(zhí)行的狀態(tài)。
格式:SWI 《immed_8》
其中:
immed_8 符號表達(dá)式,其取值范圍為的整數(shù)。
SWI指令引起SWI異常。這意味著處理器狀態(tài)切換到ARM態(tài),處理器模式切換到管理模式的,CPSR保存到管理模式中,執(zhí)行轉(zhuǎn)移SWI到向量地址。
處理器忽略immed_8,但immed_8出現(xiàn)在指令操作碼的位[7:0]中。而異常處理程序用它來確定正在請求何種服務(wù)。
注釋:
這條指令不影響條件碼標(biāo)志。
例:
SWI 12
2 Thumb斷點指令
格式:
BRKT immed_8
其中:
immed_8 符號表達(dá)式,取值范圍為0~255的整數(shù)。
注釋:
BKPT(BreakPoinT)指令引起處理器進(jìn)入調(diào)試模式。調(diào)試工具利用這一特點調(diào)查到達(dá)特定地址的指令時的系統(tǒng)狀態(tài)。
盡管immed_8出現(xiàn)在指令操作碼的位[7:8]中,處理器忽略immed_8。調(diào)試器用它來存儲有關(guā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é)最后通過比較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
?。?) 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匯編器對ARM的寄存器進(jìn)行了預(yù)定義,所有的寄存器和協(xié)處理器都是大小寫敏感的。預(yù)定義的寄存器如表3—7所示。
(1) 定義的寄存器名
R0~R15
R0~r15
a1~a4
v1~v8
sp和SP
Ir和LR
Pc和PC
Sl和SL
表3---7為ARM寄存器列表及含義
寄存器特殊定義其它定義含義
R15R14R13R12R11R10R9R8R7R6R5R4R3R2R1R0V8V7V6V5V4V3V2V1a4a3a2a1PCLRSPIPFPSLSBWR程序計數(shù)器鏈接寄存器堆棧指針程序調(diào)用暫存寄存器變量寄存器8/幀指針(ARM狀態(tài))變量寄存器7/堆棧上限指針(ARM)變量寄存器6/基址寄存器(進(jìn)程ID/重入/共享庫中)變量寄存器5變量寄存器4(Thumb狀態(tài)工作寄存器)變量寄存器3變量寄存器2變量寄存器1參數(shù)/結(jié)果/暫寄存器4參數(shù)/結(jié)果/暫寄存器3參數(shù)/結(jié)果/暫寄存器2參數(shù)/結(jié)果/暫寄存器1
R0~R3通常用來傳遞參數(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
?。?)定義的浮點數(shù)寄存器名
f0~f7
F0~F7
?。?)定義的協(xié)處理器名
p0~p15
c0~c15
2 內(nèi)置變量
表3—8列出了ARM匯編器所定義的內(nèi)置變量,值得注意的是內(nèi)置變量的設(shè)置不能用SETA,SETL,或SETS等表示詞來設(shè)置,只能用字符或條件表達(dá)式來設(shè)置。例如:
IF {ARCHITECTURE}=“4T”
表3—8 變量含義
(PC )或者(VAR)或者@(TRUE)(FALSE)(OPT)(CONFIG)(ENDIAN)(CODESIZE)(CPU)(ARCHITECTURE)(PCSTOREOFFSET)當(dāng)前指令的地址存儲區(qū)計數(shù)器的當(dāng)前值邏輯常量為真邏輯常量為假當(dāng)前設(shè)置列表選項,OPT用來保存當(dāng)前列表選項,改變選項值,恢復(fù)設(shè)置它的原始值如果匯編器在ARM模式下值為32,如果匯編在Thumb 模式下值為16如果匯編器在big—endian模式下為big,如果匯編器在某些方面little—endian模式下值為little如果匯編Thumb代碼值為16,否則為32選定的CPU符號,如果沒有說明,則為genericARM選定的ARM架構(gòu)的值,3,3M,4,4T,4TxMSTRpc,[…]或STM Rb,(…PC)的地址和PC的存儲值之間的偏移量
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)的非字對準(zhǔn)地址;
1020字節(jié)以內(nèi)的字對準(zhǔn)地址。
寄存器相關(guān)的表達(dá)式由1個寄存器加或減1個數(shù)字常數(shù)組成(見“ⅴ”或者M(jìn)PA介紹。)程序相關(guān)的表達(dá)式由PC加或減1個數(shù)字組成,一般它可為標(biā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)的非對準(zhǔn)地址;
256KB以內(nèi)的字對準(zhǔn)地址。
注釋:
ADRL偽指令通常匯編成2條指令,即使地址在第1條指令已經(jīng)產(chǎn)生,也會產(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偽指令
功能:將一個雙精度的浮點常量放進(jìn)
格式:
LDFD{condition} fp-register,=expression
其中:
condition 可選的條件代碼。
fp-register 讀取的浮點寄存器。
Expression 浮點常量。匯編器通常把放在一個庫中,用LDFD偽指令讀進(jìn)浮點寄存器中,該浮點常量用2個字存放。PC與該常量的偏移量不得超過4KB。
注釋:
浮點數(shù)常量的范圍是:
最大值 1.79769313486231571e+308
最小值2.22507385850720138e—308ADR
注意;只有系統(tǒng)中有浮點加速器FPA(Floating Point Accelerator)時,才能使用該指令。
例:
LDFD f1,=3.12E106
4 LDFS 偽指令
功能:將一個單精度的浮點數(shù)常量放進(jìn)一個浮點數(shù)寄存器。
格式:
LDFS{condition} fp-register,=expression
其中:
condition 可選的條件代碼。
fp-register 讀取的浮點寄存器。
Expression 浮點常量。匯編器通常把該常量放在一個庫中,用LDFD偽指令讀進(jìn)浮點寄存器中,該浮點常量用2個字存放。PC與該常量的偏移量不得超過4KB。
注釋:
浮點數(shù)常理的范圍是:
最大值:3.40282347e+38F
最小值:1.17549435e—38F
注意:只有系統(tǒng)中有一個浮點加速器時,才能使用該指令。
例:
LDFS f1,=3.12E---6
5 LDR 偽指令
功能:將一個32位常量或地址讀取至寄存器。
格式:
LDR{condition} register,=[expression|Label-expression]
其中:
condition 可選的條件代碼。
register 讀取的寄存器。
expression 數(shù)字常量:
如果該數(shù)字常量在MOV或MVN指令的范圍中,匯編器會產(chǎn)生合適的指令;
如果該數(shù)字量不在MOV或MVN指令的范圍中,匯編器把該常量于程序后,用程序相關(guān)的LDR偽指令讀取,PC與該常量的偏移量不得超過4KB。
Label-expression 程序相關(guān)的或外部的表達(dá)式。匯編器將其存放在程序后的常量庫(稱為文字池(literal pool))中,用程序相關(guān)的LDR偽指令讀取,PC與與該常量的偏移量不得超過4KB。
注釋:
LDR偽指令的使用有兩個目的:
對于不能被MOV和MVN指令所讀取的立即數(shù),將其變成常量,進(jìn)行讀取:
將一個程序相關(guān)的或外部的表達(dá)式讀取進(jìn)寄存器中。
例:
LDR R1, =0xfff
LDR R2, =place
6 NOP偽指令
功能: 產(chǎn)生空操作代碼。即:MOV R0,R0.
格式:
NOP
注釋:
該指令不能帶條件使用,也不能改變條件碼.
評論
查看更多