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