ARM指令詳解

詳細介紹ARM指令集1- - 首先詳細介紹ARM指令集,ARM指令集包括標準ARM指令集和Thumb指令集,並介紹ARM的宏彙編以及ARM彙編語言編程 1 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,#±]{!} 例: LDR R0,[R1,#5]! ;((R1+5)→R0,(R1)+5→R1 ②寄存器偏移[Rn,#±Rm{!} 例 LDR R0,[R!R1,-R2] ;((R1)-(R2))→R0 ③移位寄存器偏移 [Rn, ±Rm,LSL #{!} [Rn, ±Rm,LSL #{!} [Rn, ±Rm,ASR #{!} [Rn, ±Rm,ROR #{!} [Rn, ±Rm,RPX]{!} 例: LDR R0,[R1,R2,LSL #2] ;((R1)+(R2)*4→R0 (3)後變址偏聽偏信移尋址([Rn],偏移量) Rn的值用作傳送數據的存儲器地址。在數據傳送後,偏移量加到Rn中,結果寫回到Rn。Rn不允許是R15。該尋址方式又分爲下列3種: ①立即數偏移[Rn],#± 例: LDR R0,[R1],#4 ;((R1))→R0,(R1)+4→R1 ②寄存器偏移[Rn],±Rm 例: LDR R0,[R3],-R8 ;((R3))→R0,(R3)-(R8)→R3 ③移位寄存器偏移 [Rn],±Rm,LSL# [Rn],±Rm,LSR# [Rn],±Rm,ASR# [Rn],±Rm,ROR# [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,#±]{!} 例: 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,#±]{!}); (3)後變址偏移尋址([Rn],#±); (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,]{!} ;((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], 後變址指的是將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,]{!} (3) 程序相對偏移(pregram-relatve) LDR|STR{<條件碼>}H|SH|SB Rd,Label (4) 後變址(post-indexed offset) LDR|STR{<條件碼>}H|SH|SB Rd,[Rn], 其中: 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,]{!} (3) 程序相對偏移(pregram-relatve) LDR|STR{<條件碼>}D Rd,LABEL (4) 後變地址格式(post-indexed offset) LDR|STR{<條件碼式>}D Rd,[Rn], 其中: 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{<條件碼>}Rn{!}<寄存器> (2) 非用戶模式下,用下面可以同時把當前的SPSR寫入CPSR中,轉向用戶模式,寄存器組飲包含PC. LDM{<條件碼>}Rn{!},<寄存器組+PC>^ (3) 非用戶模式下,用下面格式可以實現訪問用戶模式的寄存器,但寄存器組不包含PC. LDM|STM{<條件碼>}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) {<條件碼>}{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{條件碼}Rd,Rm,Rs 其中: B或T。B意味着使用Rm的低端(位[15:0]),T意味着使用Rs的高端(位[31:16])。 B或T。B意味着使用Rm的低端(位[15:0]),T意味着使用Rs的高端(位[31:16])。 Rd 結果寄存器。 Rm,Rs 乘數寄存器。 R15不能用於Rd,Rm和Rs。Rd、Rm、Rs可用相同的寄存器。 (5) SMLA{條件碼}Rd,Rm,Rs可用相同的寄存器。其中: 、、Rm和Rn含義同SMUL指令。 R15不能用於Rd、Rm和Rs。Rd、Rm、Rs可用相同的寄存器。 (6) SMULW{條件碼}Rd,Rm,Rs 其中: 、Rd、Rm、Rs和Rn含義同SMUL指令。 R15不能用於Rd、Rm和Rs。Rd、Rm、Rs可用相同的寄存器。 (7) SMULW{條件碼}Rd,Rm,Rs 其中: 、Rd、Rm、Rs和Rn含義同SMUL指令。 R15不能用作Rd、Rm、Rs或Rn的任何一個。任何Rd、Rm、Rs或Rn可用相同的寄存器。 (8) SMULW{條件碼}Rd,Rm,Rs,Rn 其中: 、Rd、Rm、Rs和Rn含義同SMUL指令。 R15不能用作Rd、Rm、Rs或Rn的任何一個。任何Rd、Rm、Rs或Rn可用相同的寄存器。 (9) SMULW{條件碼}RdLo,RdHi,Rm,Rs 其中: 含義同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}{<條件碼>}

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