3.1 ARM微處理器的指令集概述
3.1.1 ARM微處理器的指令的分類與格式
ARM微處理器的指令集是加載/存儲(chǔ)型的,,也即指令集僅能處理寄存器中的數(shù)據(jù),,而且處理結(jié)果都要放回寄存器中,,而對(duì)系統(tǒng)存儲(chǔ)器的訪問則需要通過專門的加載/存儲(chǔ)指令來完成。
ARM微處理器的指令集可以分為跳轉(zhuǎn)指令、數(shù)據(jù)處理指令,、程序狀態(tài)寄存器(PSR)處理指令、加載/存儲(chǔ)指令、協(xié)處理器指令和異常產(chǎn)生指令六大類,,具體的指令及功能如表3-1所示(表中指令為基本ARM指令,不包括派生的ARM指令),。
表3-1 ARM指令及功能描述
3.1.2 指令的條件域
當(dāng)處理器工作在ARM狀態(tài)時(shí),,幾乎所有的指令均根據(jù)CPSR中條件碼的狀態(tài)和指令的條件域有條件的執(zhí)行。當(dāng)指令的執(zhí)行條件滿足時(shí),,指令被執(zhí)行,,否則指令被忽略。
每一條ARM指令包含4位的條件碼,,位于指令的最高4位[31:28],。條件碼共有16種,每種條件碼可用兩個(gè)字符表示,,這兩個(gè)字符可以添加在指令助記符的后面和指令同時(shí)使用,。例如,,跳轉(zhuǎn)指令B可以加上后綴EQ變?yōu)锽EQ表示“相等則跳轉(zhuǎn)”,即當(dāng)CPSR中的Z標(biāo)志置位時(shí)發(fā)生跳轉(zhuǎn),。
在16種條件標(biāo)志碼中,,只有15種可以使用,如表3-2所示,,第16種(1111)為系統(tǒng)保留,,暫時(shí)不能使用。
表3-2 指令的條件碼
3.2 ARM指令的尋址方式
所謂尋址方式就是處理器根據(jù)指令中給出的地址信息來尋找物理地址的方式,。目前ARM指令系統(tǒng)支持如下幾種常見的尋址方式,。
3.2.1 立即尋址
立即尋址也叫立即數(shù)尋址,這是一種特殊的尋址方式,,操作數(shù)本身就在指令中給出,,只要取出指令也就取到了操作數(shù)。這個(gè)操作數(shù)被稱為立即數(shù),,對(duì)應(yīng)的尋址方式也就叫做立即尋址,。例如以下指令:
ADD R0,R0,,#1 ,;R0←R0+1
ADD R0,R0,,#0x3f ,;R0←R0+0x3f
在以上兩條指令中,第二個(gè)源操作數(shù)即為立即數(shù),,要求以“?!睘榍熬Y,對(duì)于以十六進(jìn)制表示的立即數(shù),,還要求在“?!焙蠹由稀?x”或“&”。
3.2.2 寄存器尋址
寄存器尋址就是利用寄存器中的數(shù)值作為操作數(shù),,這種尋址方式是各類微處理器經(jīng)常采用的一種方式,,也是一種執(zhí)行效率較高的尋址方式。以下指令:
ADD R0,,R1,,R2 ;R0←R1+R2
該指令的執(zhí)行效果是將寄存器R1和R2的內(nèi)容相加,,其結(jié)果存放在寄存器R0中,。
3.2.2 寄存器間接尋址
寄存器間接尋址就是以寄存器中的值作為操作數(shù)的地址,而操作數(shù)本身存放在存儲(chǔ)器中,。例如以下指令:
ADD R0,,R1,,[R2] ;R0←R1+[R2]
LDR R0,,[R1] ,;R0←[R1]
STR R0,[R1] ,;[R1]←R0
在第一條指令中,,以寄存器R2的值作為操作數(shù)的地址,在存儲(chǔ)器中取得一個(gè)操作數(shù)后與R1相加,,結(jié)果存入寄存器R0中,。
第二條指令將以R1的值為地址的存儲(chǔ)器中的數(shù)據(jù)傳送到R0中。
第三條指令將R0的值傳送到以R1的值為地址的存儲(chǔ)器中,。
3.2.3 基址變址尋址
基址變址尋址就是將寄存器(該寄存器一般稱作基址寄存器)的內(nèi)容與指令中給出的地址偏移量相加,,從而得到一個(gè)操作數(shù)的有效地址。變址尋址方式常用于訪問某基地址附近的地址單元,。采用變址尋址方式的指令常見有以下幾種形式,,如下所示:
LDR R0,[R1,,#4] ,;R0←[R1+4]
LDR R0,[R1,,#4],! ;R0←[R1+4],、R1←R1+4
LDR R0,,[R1] ,#4 ,;R0←[R1],、R1←R1+4
LDR R0,,[R1,,R2] ;R0←[R1+R2]
在第一條指令中,,將寄存器R1的內(nèi)容加上4形成操作數(shù)的有效地址,,從而取得操作數(shù)存入寄存器R0中。
在第二條指令中,,將寄存器R1的內(nèi)容加上4形成操作數(shù)的有效地址,,從而取得操作數(shù)存入寄存器R0中,然后,,R1的內(nèi)容自增4個(gè)字節(jié),。
在第三條指令中,,以寄存器R1的內(nèi)容作為操作數(shù)的有效地址,從而取得操作數(shù)存入寄存器R0中,,然后,,R1的內(nèi)容自增4個(gè)字節(jié),。
在第四條指令中,,將寄存器R1的內(nèi)容加上寄存器R2的內(nèi)容形成操作數(shù)的有效地址,從而取得操作數(shù)存入寄存器R0中,。
3.2.4 多寄存器尋址
采用多寄存器尋址方式,,一條指令可以完成多個(gè)寄存器值的傳送。這種尋址方式可以用一條指令完成傳送最多16個(gè)通用寄存器的值,。以下指令:
LDMIA R0,,{R1,R2,,R3,,R4} ;R1←[R0]
??;R2←[R0+4]
,;R3←[R0+8]
?。籖4←[R0+12]
該指令的后綴IA表示在每次執(zhí)行完加載/存儲(chǔ)操作后,,R0按字長度增加,,因此,指令可將連續(xù)存儲(chǔ)單元的值傳送到R1~R4,。
3.2.5 相對(duì)尋址
與基址變址尋址方式相類似,,相對(duì)尋址以程序計(jì)數(shù)器PC的當(dāng)前值為基地址,指令中的地址標(biāo)號(hào)作為偏移量,,將兩者相加之后得到操作數(shù)的有效地址,。以下程序段完成子程序的調(diào)用和返回,跳轉(zhuǎn)指令BL采用了相對(duì)尋址方式:
BL NEXT ,;跳轉(zhuǎn)到子程序NEXT處執(zhí)行
……
NEXT
……
MOV PC,,LR ;從子程序返回
3.2.6 堆棧尋址
堆棧是一種數(shù)據(jù)結(jié)構(gòu),,按先進(jìn)后出(First In Last Out,,F(xiàn)ILO)的方式工作,使用一個(gè)稱作堆棧指針的專用寄存器指示當(dāng)前的操作位置,堆棧指針總是指向棧頂,。
當(dāng)堆棧指針指向最后壓入堆棧的數(shù)據(jù)時(shí),,稱為滿堆棧(Full Stack),而當(dāng)堆棧指針指向下一個(gè)將要放入數(shù)據(jù)的空位置時(shí),,稱為空堆棧(Empty Stack),。
同時(shí),根據(jù)堆棧的生成方式,,又可以分為遞增堆棧(Ascending Stack)和遞減堆棧(Decending Stack),,當(dāng)堆棧由低地址向高地址生成時(shí),稱為遞增堆棧,,當(dāng)堆棧由高地址向低地址生成時(shí),,稱為遞減堆棧。這樣就有四種類型的堆棧工作方式,,ARM微處理器支持這四種類型的堆棧工作方式,,即:
- 滿遞增堆棧:堆棧指針指向最后壓入的數(shù)據(jù),,且由低地址向高地址生成,。
- 滿遞減堆棧:堆棧指針指向最后壓入的數(shù)據(jù),,且由高地址向低地址生成,。
- 空遞增堆棧:堆棧指針指向下一個(gè)將要放入數(shù)據(jù)的空位置,,且由低地址向高地址生成,。
- 空遞減堆棧:堆棧指針指向下一個(gè)將要放入數(shù)據(jù)的空位置,,且由高地址向低地址生成,。
3.3 ARM指令集
本節(jié)對(duì)ARM指令集的六大類指令進(jìn)行詳細(xì)的描述。
3.3.1 跳轉(zhuǎn)指令
跳轉(zhuǎn)指令用于實(shí)現(xiàn)程序流程的跳轉(zhuǎn),,在ARM程序中有兩種方法可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn):
— 使用專門的跳轉(zhuǎn)指令,。
— 直接向程序計(jì)數(shù)器PC寫入跳轉(zhuǎn)地址值。
通過向程序計(jì)數(shù)器PC寫入跳轉(zhuǎn)地址值,,可以實(shí)現(xiàn)在4GB的地址空間中的任意跳轉(zhuǎn),,在跳轉(zhuǎn)之前結(jié)合使用
MOV LR,PC
等類似指令,,可以保存將來的返回地址值,,從而實(shí)現(xiàn)在4GB連續(xù)的線性地址空間的子程序調(diào)用,。
ARM指令集中的跳轉(zhuǎn)指令可以完成從當(dāng)前指令向前或向后的32MB的地址空間的跳轉(zhuǎn),,包括以下4條指令:
— B 跳轉(zhuǎn)指令
— BL 帶返回的跳轉(zhuǎn)指令
— BLX 帶返回和狀態(tài)切換的跳轉(zhuǎn)指令
— BX 帶狀態(tài)切換的跳轉(zhuǎn)指令
1、 B指令
B指令的格式為:
B{條件} 目標(biāo)地址
B指令是最簡單的跳轉(zhuǎn)指令。一旦遇到一個(gè) B 指令,,ARM 處理器將立即跳轉(zhuǎn)到給定的目標(biāo)地址,,從那里繼續(xù)執(zhí)行。注意存儲(chǔ)在跳轉(zhuǎn)指令中的實(shí)際值是相對(duì)當(dāng)前PC值的一個(gè)偏移量,,而不是一個(gè)絕對(duì)地址,,它的值由匯編器來計(jì)算(參考尋址方式中的相對(duì)尋址)。它是 24 位有符號(hào)數(shù),,左移兩位后有符號(hào)擴(kuò)展為 32 位,,表示的有效偏移為 26 位(前后32MB的地址空間)。以下指令:
B Label ,;程序無條件跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行
CMP R1,,#0 ;當(dāng)CPSR寄存器中的Z條件碼置位時(shí),,程序跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行
BEQ Label
2,、 BL指令
BL指令的格式為:
BL{條件} 目標(biāo)地址
BL 是另一個(gè)跳轉(zhuǎn)指令,但跳轉(zhuǎn)之前,,會(huì)在寄存器R14中保存PC的當(dāng)前內(nèi)容,,因此,可以通過將R14 的內(nèi)容重新加載到PC中,,來返回到跳轉(zhuǎn)指令之后的那個(gè)指令處執(zhí)行,。該指令是實(shí)現(xiàn)子程序調(diào)用的一個(gè)基本但常用的手段。以下指令:
BL Label ,;當(dāng)程序無條件跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行時(shí),,同時(shí)將當(dāng)前的PC值保存到R14中
3、 BLX指令
BLX指令的格式為:
BLX 目標(biāo)地址
BLX指令從ARM指令集跳轉(zhuǎn)到指令中所指定的目標(biāo)地址,,并將處理器的工作狀態(tài)有ARM狀態(tài)切換到Thumb狀態(tài),,該指令同時(shí)將PC的當(dāng)前內(nèi)容保存到寄存器R14中。因此,,當(dāng)子程序使用Thumb指令集,,而調(diào)用者使用ARM指令集時(shí),可以通過BLX指令實(shí)現(xiàn)子程序的調(diào)用和處理器工作狀態(tài)的切換,。同時(shí),,子程序的返回可以通過將寄存器R14值復(fù)制到PC中來完成。
4,、 BX指令
BX指令的格式為:
BX{條件} 目標(biāo)地址
BX指令跳轉(zhuǎn)到指令中所指定的目標(biāo)地址,,目標(biāo)地址處的指令既可以是ARM指令,也可以是Thumb指令,。
3.3.2 數(shù)據(jù)處理指令
數(shù)據(jù)處理指令可分為數(shù)據(jù)傳送指令,、算術(shù)邏輯運(yùn)算指令和比較指令等。
數(shù)據(jù)傳送指令用于在寄存器和存儲(chǔ)器之間進(jìn)行數(shù)據(jù)的雙向傳輸。
算術(shù)邏輯運(yùn)算指令完成常用的算術(shù)與邏輯的運(yùn)算,,該類指令不但將運(yùn)算結(jié)果保存在目的寄存器中,,同時(shí)更新CPSR中的相應(yīng)條件標(biāo)志位。
比較指令不保存運(yùn)算結(jié)果,,只更新CPSR中相應(yīng)的條件標(biāo)志位,。
數(shù)據(jù)處理指令包括:
— MOV 數(shù)據(jù)傳送指令
— MVN 數(shù)據(jù)取反傳送指令
— CMP 比較指令
— CMN 反值比較指令
— TST 位測試指令
— TEQ 相等測試指令
— ADD 加法指令
— ADC 帶進(jìn)位加法指令
— SUB 減法指令
— SBC 帶借位減法指令
— RSB 逆向減法指令
— RSC 帶借位的逆向減法指令
— AND 邏輯與指令
— ORR 邏輯或指令
— EOR 邏輯異或指令
— BIC 位清除指令
1、 MOV指令
MOV指令的格式為:
MOV{條件}{S} 目的寄存器,,源操作數(shù)
MOV指令可完成從另一個(gè)寄存器,、被移位的寄存器或?qū)⒁粋€(gè)立即數(shù)加載到目的寄存器。其中S選項(xiàng)決定指令的操作是否影響CPSR中條件標(biāo)志位的值,,當(dāng)沒有S時(shí)指令不更新CPSR中條件標(biāo)志位的值,。
指令示例:
MOV R1,R0 ,;將寄存器R0的值傳送到寄存器R1
MOV PC,,R14 ;將寄存器R14的值傳送到PC,,常用于子程序返回
MOV R1,,R0,LSL#3 ,;將寄存器R0的值左移3位后傳送到R1
2,、 MVN指令
MVN指令的格式為:
MVN{條件}{S} 目的寄存器,源操作數(shù)
MVN指令可完成從另一個(gè)寄存器,、被移位的寄存器,、或?qū)⒁粋€(gè)立即數(shù)加載到目的寄存器。與MOV指令不同之處是在傳送之前按位被取反了,,即把一個(gè)被取反的值傳送到目的寄存器中,。其中S決定指令的操作是否影響CPSR中條件標(biāo)志位的值,當(dāng)沒有S時(shí)指令不更新CPSR中條件標(biāo)志位的值,。
指令示例:
MVN R0,,#0 ;將立即數(shù)0取反傳送到寄存器R0中,,完成后R0=-1
3,、 CMP指令
CMP指令的格式為:
CMP{條件} 操作數(shù)1,操作數(shù)2
CMP指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行比較,,同時(shí)更新CPSR中條件標(biāo)志位的值,。該指令進(jìn)行一次減法運(yùn)算,但不存儲(chǔ)結(jié)果,,只更改條件標(biāo)志位,。標(biāo)志位表示的是操作數(shù)1與操作數(shù)2的關(guān)系(大,、小、相等),,例如,,當(dāng)操作數(shù)1大于操作操作數(shù)2,,則此后的有GT 后綴的指令將可以執(zhí)行,。
指令示例:
CMP R1,R0 , ; ,;將寄存器R1的值與寄存器R0的值相減,,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
CMP R1,#100 ,;將寄存器R1的值與立即數(shù)100相減,,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
4、 CMN指令
CMN指令的格式為:
CMN{條件} 操作數(shù)1,,操作數(shù)2
CMN指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)取反后進(jìn)行比較,,同時(shí)更新CPSR中條件標(biāo)志位的值。該指令實(shí)際完成操作數(shù)1和操作數(shù)2相加,,并根據(jù)結(jié)果更改條件標(biāo)志位,。
指令示例:
CMN R1,R0 ,;將寄存器R1的值與寄存器R0的值相加,,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
CMN R1,#100 ,;將寄存器R1的值與立即數(shù)100相加,,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
5、 TST指令
TST指令的格式為:
TST{條件} 操作數(shù)1,,操作數(shù)2
TST指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行按位的與運(yùn)算,,并根據(jù)運(yùn)算結(jié)果更新CPSR中條件標(biāo)志位的值。操作數(shù)1是要測試的數(shù)據(jù),,而操作數(shù)2是一個(gè)位掩碼,,該指令一般用來檢測是否設(shè)置了特定的位。
指令示例:
TST R1,,#%1 ,;用于測試在寄存器R1中是否設(shè)置了最低位(%表示二進(jìn)制數(shù))
TST R1,#0xffe ,;將寄存器R1的值與立即數(shù)0xffe按位與,,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
6、 TEQ指令
TEQ指令的格式為:
TEQ{條件} 操作數(shù)1,,操作數(shù)2
TEQ指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行按位的異或運(yùn)算,,并根據(jù)運(yùn)算結(jié)果更新CPSR中條件標(biāo)志位的值,。該指令通常用于比較操作數(shù)1和操作數(shù)2是否相等。
指令示例:
TEQ R1,,R2 ,;將寄存器R1的值與寄存器R2的值按位異或,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
7,、 ADD指令
ADD指令的格式為:
ADD{條件}{S} 目的寄存器,,操作數(shù)1,操作數(shù)2
ADD指令用于把兩個(gè)操作數(shù)相加,,并將結(jié)果存放到目的寄存器中,。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,,被移位的寄存器,,或一個(gè)立即數(shù)。
指令示例:
ADD R0,,R1,,R2 ; R0 = R1 + R2
ADD R0,,R1,,#256 ; R0 = R1 + 256
ADD R0,,R2,,R3,LSL#1 ,; R0 = R2 + (R3 << 1)
8,、 ADC指令
ADC指令的格式為:
ADC{條件}{S} 目的寄存器,操作數(shù)1,,操作數(shù)2
ADC指令用于把兩個(gè)操作數(shù)相加,,再加上CPSR中的C條件標(biāo)志位的值,并將結(jié)果存放到目的寄存器中,。它使用一個(gè)進(jìn)位標(biāo)志位,,這樣就可以做比32位大的數(shù)的加法,注意不要忘記設(shè)置S后綴來更改進(jìn)位標(biāo)志,。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,,或一個(gè)立即數(shù),。
以下指令序列完成兩個(gè)128位數(shù)的加法,第一個(gè)數(shù)由高到低存放在寄存器R7~R4,,第二個(gè)數(shù)由高到低存放在寄存器R11~R8,,運(yùn)算結(jié)果由高到低存放在寄存器R3~R0:
ADDS R0,,R4,R8 ,; 加低端的字
ADCS R1,,R5,R9 ,; 加第二個(gè)字,,帶進(jìn)位
ADCS R2,R6,,R10 ,; 加第三個(gè)字,,帶進(jìn)位
ADC R3,,R7,R11 ,; 加第四個(gè)字,,帶進(jìn)位
9、 SUB指令
SUB指令的格式為:
SUB{條件}{S} 目的寄存器,,操作數(shù)1,,操作數(shù)2
SUB指令用于把操作數(shù)1減去操作數(shù)2,并將結(jié)果存放到目的寄存器中,。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,,或一個(gè)立即數(shù),。該指令可用于有符號(hào)數(shù)或無符號(hào)數(shù)的減法運(yùn)算。
指令示例:
SUB R0,,R1,,R2 ; R0 = R1 - R2
SUB R0,,R1,,#256 ; R0 = R1 - 256
SUB R0,,R2,,R3,LSL#1 ,; R0 = R2 - (R3 << 1)
10,、SBC指令
SBC指令的格式為:
SBC{條件}{S} 目的寄存器,操作數(shù)1,,操作數(shù)2
SBC指令用于把操作數(shù)1減去操作數(shù)2,,再減去CPSR中的C條件標(biāo)志位的反碼,,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,,被移位的寄存器,或一個(gè)立即數(shù),。該指令使用進(jìn)位標(biāo)志來表示借位,,這樣就可以做大于32位的減法,注意不要忘記設(shè)置S后綴來更改進(jìn)位標(biāo)志,。該指令可用于有符號(hào)數(shù)或無符號(hào)數(shù)的減法運(yùn)算,。
指令示例:
SUBS R0,R1,,R2 ,; R0 = R1 - R2 - !C,,并根據(jù)結(jié)果設(shè)置CPSR的進(jìn)位標(biāo)志位
11,、RSB指令
RSB指令的格式為:
RSB{條件}{S} 目的寄存器,操作數(shù)1,,操作數(shù)2
RSB指令稱為逆向減法指令,,用于把操作數(shù)2減去操作數(shù)1,并將結(jié)果存放到目的寄存器中,。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,,或一個(gè)立即數(shù),。該指令可用于有符號(hào)數(shù)或無符號(hào)數(shù)的減法運(yùn)算。
指令示例:
RSB R0,,R1,,R2 ; R0 = R2 – R1
RSB R0,,R1,,#256 ; R0 = 256 – R1
RSB R0,,R2,,R3,LSL#1 ,; R0 = (R3 << 1) - R2
12,、RSC指令
RSC指令的格式為:
RSC{條件}{S} 目的寄存器,操作數(shù)1,,操作數(shù)2
RSC指令用于把操作數(shù)2減去操作數(shù)1,,再減去CPSR中的C條件標(biāo)志位的反碼,,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,,被移位的寄存器,或一個(gè)立即數(shù),。該指令使用進(jìn)位標(biāo)志來表示借位,,這樣就可以做大于32位的減法,注意不要忘記設(shè)置S后綴來更改進(jìn)位標(biāo)志,。該指令可用于有符號(hào)數(shù)或無符號(hào)數(shù)的減法運(yùn)算,。
指令示例:
RSC R0,R1,,R2 ,; R0 = R2 – R1 - !C
13,、AND指令
AND指令的格式為:
AND{條件}{S} 目的寄存器,,操作數(shù)1,,操作數(shù)2
AND指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯與運(yùn)算,,并把結(jié)果放置到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,,被移位的寄存器,或一個(gè)立即數(shù),。該指令常用于屏蔽操作數(shù)1的某些位,。
指令示例:
AND R0,R0,,#3 ,; 該指令保持R0的0、1位,,其余位清零,。
14、ORR指令
ORR指令的格式為:
ORR{條件}{S} 目的寄存器,,操作數(shù)1,,操作數(shù)2
ORR指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯或運(yùn)算,并把結(jié)果放置到目的寄存器中,。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,,或一個(gè)立即數(shù),。該指令常用于設(shè)置操作數(shù)1的某些位,。
指令示例:
ORR R0,R0,,#3 ,; 該指令設(shè)置R0的0、1位,,其余位保持不變,。
15、EOR指令
EOR指令的格式為:
EOR{條件}{S} 目的寄存器,,操作數(shù)1,,操作數(shù)2
EOR指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯異或運(yùn)算,并把結(jié)果放置到目的寄存器中,。操作數(shù)1應(yīng)是一個(gè)寄存器,,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,,或一個(gè)立即數(shù),。該指令常用于反轉(zhuǎn)操作數(shù)1的某些位。
指令示例:
EOR R0,,R0,,#3 ; 該指令反轉(zhuǎn)R0的0,、1位,,其余位保持不變。
16,、BIC指令
BIC指令的格式為:
BIC{條件}{S} 目的寄存器,,操作數(shù)1,操作數(shù)2
BIC指令用于清除操作數(shù)1的某些位,,并把結(jié)果放置到目的寄存器中,。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,,被移位的寄存器,,或一個(gè)立即數(shù)。操作數(shù)2為32位的掩碼,,如果在掩碼中設(shè)置了某一位,,則清除這一位。未設(shè)置的掩碼位保持不變,。
指令示例:
BIC R0,,R0,#%1011 ; 該指令清除 R0 中的位 0,、1,、和 3,其余的位保持不變,。
3.3.3 乘法指令與乘加指令
ARM微處理器支持的乘法指令與乘加指令共有6條,,可分為運(yùn)算結(jié)果為32位和運(yùn)算結(jié)果為64位兩類,與前面的數(shù)據(jù)處理指令不同,,指令中的所有操作數(shù),、目的寄存器必須為通用寄存器,不能對(duì)操作數(shù)使用立即數(shù)或被移位的寄存器,,同時(shí),,目的寄存器和操作數(shù)1必須是不同的寄存器。
乘法指令與乘加指令共有以下6條:
— MUL 32位乘法指令
— MLA 32位乘加指令
— SMULL 64位有符號(hào)數(shù)乘法指令
— SMLAL 64位有符號(hào)數(shù)乘加指令
— UMULL 64位無符號(hào)數(shù)乘法指令
— UMLAL 64位無符號(hào)數(shù)乘加指令
1,、 MUL指令
MUL指令的格式為:
MUL{條件}{S} 目的寄存器,,操作數(shù)1,操作數(shù)2
MUL指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,,并把結(jié)果放置到目的寄存器中,,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位。其中,,操作數(shù)1和操作數(shù)2均為32位的有符號(hào)數(shù)或無符號(hào)數(shù),。
指令示例:
MUL R0,R1,,R2 ,;R0 = R1 × R2
MULS R0,R1,,R2 ;R0 = R1 × R2,,同時(shí)設(shè)置CPSR中的相關(guān)條件標(biāo)志位
2,、 MLA指令
MLA指令的格式為:
MLA{條件}{S} 目的寄存器,操作數(shù)1,,操作數(shù)2,,操作數(shù)3
MLA指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,再將乘積加上操作數(shù)3,,并把結(jié)果放置到目的寄存器中,,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位。其中,,操作數(shù)1和操作數(shù)2均為32位的有符號(hào)數(shù)或無符號(hào)數(shù),。
指令示例:
MLA R0,R1,R2,,R3 ,;R0 = R1 × R2 + R3
MLAS R0,R1,,R2,,R3 ;R0 = R1 × R2 + R3,,同時(shí)設(shè)置CPSR中的相關(guān)條件標(biāo)志位
3,、 SMULL指令
SMULL指令的格式為:
SMULL{條件}{S} 目的寄存器Low,目的寄存器低High,,操作數(shù)1,,操作數(shù)2
SMULL指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,并把結(jié)果的低32位放置到目的寄存器Low中,,結(jié)果的高32位放置到目的寄存器High中,,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位。其中,,操作數(shù)1和操作數(shù)2均為32位的有符號(hào)數(shù),。
指令示例:
SMULL R0,R1,,R2,,R3 ;R0 = (R2 × R3)的低32位
??;R1 = (R2 × R3)的高32位
4、 SMLAL指令
SMLAL指令的格式為:
SMLAL{條件}{S} 目的寄存器Low,,目的寄存器低High,,操作數(shù)1,操作數(shù)2
SMLAL指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,,并把結(jié)果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,,結(jié)果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位,。其中,,操作數(shù)1和操作數(shù)2均為32位的有符號(hào)數(shù)。
對(duì)于目的寄存器Low,,在指令執(zhí)行前存放64位加數(shù)的低32位,,指令執(zhí)行后存放結(jié)果的低32位。
對(duì)于目的寄存器High,,在指令執(zhí)行前存放64位加數(shù)的高32位,,指令執(zhí)行后存放結(jié)果的高32位,。
指令示例:
SMLAL R0,R1,,R2,,R3 ;R0 = (R2 × R3)的低32位 + R0
??;R1 = (R2 × R3)的高32位 + R1
5、 UMULL指令
UMULL指令的格式為:
UMULL{條件}{S} 目的寄存器Low,,目的寄存器低High,,操作數(shù)1,操作數(shù)2
UMULL指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,,并把結(jié)果的低32位放置到目的寄存器Low中,,結(jié)果的高32位放置到目的寄存器High中,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位,。其中,,操作數(shù)1和操作數(shù)2均為32位的無符號(hào)數(shù)。
指令示例:
UMULL R0,,R1,,R2,R3 ,;R0 = (R2 × R3)的低32位
?。籖1 = (R2 × R3)的高32位
6,、 UMLAL指令
UMLAL指令的格式為:
UMLAL{條件}{S} 目的寄存器Low,,目的寄存器低High,操作數(shù)1,,操作數(shù)2
UMLAL指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,,并把結(jié)果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,結(jié)果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位,。其中,操作數(shù)1和操作數(shù)2均為32位的無符號(hào)數(shù),。
對(duì)于目的寄存器Low,在指令執(zhí)行前存放64位加數(shù)的低32位,,指令執(zhí)行后存放結(jié)果的低32位,。
對(duì)于目的寄存器High,在指令執(zhí)行前存放64位加數(shù)的高32位,,指令執(zhí)行后存放結(jié)果的高32位,。
指令示例:
UMLAL R0,R1,R2,,R3 ,;R0 = (R2 × R3)的低32位 + R0
,;R1 = (R2 × R3)的高32位 + R1
3.3.4 程序狀態(tài)寄存器訪問指令
ARM微處理器支持程序狀態(tài)寄存器訪問指令,,用于在程序狀態(tài)寄存器和通用寄存器之間傳送數(shù)據(jù),程序狀態(tài)寄存器訪問指令包括以下兩條:
— MRS 程序狀態(tài)寄存器到通用寄存器的數(shù)據(jù)傳送指令
— MSR 通用寄存器到程序狀態(tài)寄存器的數(shù)據(jù)傳送指令
1,、 MRS指令
MRS指令的格式為:
MRS{條件} 通用寄存器,,程序狀態(tài)寄存器(CPSR或SPSR)
MRS指令用于將程序狀態(tài)寄存器的內(nèi)容傳送到通用寄存器中。該指令一般用在以下幾種情況:
?。?nbsp; 當(dāng)需要改變程序狀態(tài)寄存器的內(nèi)容時(shí),,可用MRS將程序狀態(tài)寄存器的內(nèi)容讀入通用寄存器,修改后再寫回程序狀態(tài)寄存器,。
?。?nbsp; 當(dāng)在異常處理或進(jìn)程切換時(shí),需要保存程序狀態(tài)寄存器的值,,可先用該指令讀出程序狀態(tài)寄存器的值,,然后保存。
指令示例:
MRS R0,,CPSR ,;傳送CPSR的內(nèi)容到R0
MRS R0,SPSR ,;傳送SPSR的內(nèi)容到R0
2,、 MSR指令
MSR指令的格式為:
MSR{條件} 程序狀態(tài)寄存器(CPSR或SPSR)_<域>,操作數(shù)
MSR指令用于將操作數(shù)的內(nèi)容傳送到程序狀態(tài)寄存器的特定域中,。其中,,操作數(shù)可以為通用寄存器或立即數(shù)。<域>用于設(shè)置程序狀態(tài)寄存器中需要操作的位,,32位的程序狀態(tài)寄存器可分為4個(gè)域:
位[31:24]為條件標(biāo)志位域,,用f表示;
位[23:16]為狀態(tài)位域,,用s表示,;
位[15:8]為擴(kuò)展位域,用x表示,;
位[7:0]為控制位域,,用c表示;
該指令通常用于恢復(fù)或改變程序狀態(tài)寄存器的內(nèi)容,,在使用時(shí),,一般要在MSR指令中指明將要操作的域,。
指令示例:
MSR CPSR,R0 ,;傳送R0的內(nèi)容到CPSR
MSR SPSR,,R0 ;傳送R0的內(nèi)容到SPSR
MSR CPSR_c,,R0 ,;傳送R0的內(nèi)容到SPSR,但僅僅修改CPSR中的控制位域
3.3.5 加載/存儲(chǔ)指令
ARM微處理器支持加載/存儲(chǔ)指令用于在寄存器和存儲(chǔ)器之間傳送數(shù)據(jù),,加載指令用于將存儲(chǔ)器中的數(shù)據(jù)傳送到寄存器,,存儲(chǔ)指令則完成相反的操作。常用的加載存儲(chǔ)指令如下:
— LDR 字?jǐn)?shù)據(jù)加載指令
— LDRB 字節(jié)數(shù)據(jù)加載指令
— LDRH 半字?jǐn)?shù)據(jù)加載指令
— STR 字?jǐn)?shù)據(jù)存儲(chǔ)指令
— STRB 字節(jié)數(shù)據(jù)存儲(chǔ)指令
— STRH 半字?jǐn)?shù)據(jù)存儲(chǔ)指令
1,、LDR指令
LDR指令的格式為:
LDR{條件} 目的寄存器,,<存儲(chǔ)器地址>
LDR指令用于從存儲(chǔ)器中將一個(gè)32位的字?jǐn)?shù)據(jù)傳送到目的寄存器中。該指令通常用于從存儲(chǔ)器中讀取32位的字?jǐn)?shù)據(jù)到通用寄存器,,然后對(duì)數(shù)據(jù)進(jìn)行處理,。當(dāng)程序計(jì)數(shù)器PC作為目的寄存器時(shí),指令從存儲(chǔ)器中讀取的字?jǐn)?shù)據(jù)被當(dāng)作目的地址,,從而可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn),。該指令在程序設(shè)計(jì)中比較常用,且尋址方式靈活多樣,,請(qǐng)讀者認(rèn)真掌握,。
指令示例:
LDR R0,[R1] ,;將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0,。
LDR R0,[R1,,R2] ,;將存儲(chǔ)器地址為R1+R2的字?jǐn)?shù)據(jù)讀入寄存器R0。
LDR R0,,[R1,,#8] ;將存儲(chǔ)器地址為R1+8的字?jǐn)?shù)據(jù)讀入寄存器R0,。
LDR R0,,[R1,R2] ,! ,;將存儲(chǔ)器地址為R1+R2的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址R1+R2寫入R1,。
LDR R0,,[R1,#8] ,! ,;將存儲(chǔ)器地址為R1+8的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址R1+8寫入R1,。
LDR R0,,[R1],R2 ,;將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0,,并將新地址R1+R2寫入R1。
LDR R0,,[R1,,R2,LSL#2],! ,;將存儲(chǔ)器地址為R1+R2×4的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址R1+R2×4寫入R1,。
LDR R0,,[R1],R2,,LSL#2 ,;將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址R1+R2×4寫入R1,。
2,、LDRB指令
LDRB指令的格式為:
LDR{條件}B 目的寄存器,<存儲(chǔ)器地址>
LDRB指令用于從存儲(chǔ)器中將一個(gè)8位的字節(jié)數(shù)據(jù)傳送到目的寄存器中,,同時(shí)將寄存器的高24位清零,。該指令通常用于從存儲(chǔ)器中讀取8位的字節(jié)數(shù)據(jù)到通用寄存器,然后對(duì)數(shù)據(jù)進(jìn)行處理,。當(dāng)程序計(jì)數(shù)器PC作為目的寄存器時(shí),,指令從存儲(chǔ)器中讀取的字?jǐn)?shù)據(jù)被當(dāng)作目的地址,從而可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn),。
指令示例:
LDRB R0,,[R1] ;將存儲(chǔ)器地址為R1的字節(jié)數(shù)據(jù)讀入寄存器R0,,并將R0的高24位清零,。
LDRB R0,[R1,,#8] ,;將存儲(chǔ)器地址為R1+8的字節(jié)數(shù)據(jù)讀入寄存器R0,,并將R0的高24位清零。
3,、LDRH指令
LDRH指令的格式為:
LDR{條件}H 目的寄存器,,<存儲(chǔ)器地址>
LDRH指令用于從存儲(chǔ)器中將一個(gè)16位的半字?jǐn)?shù)據(jù)傳送到目的寄存器中,同時(shí)將寄存器的高16位清零,。該指令通常用于從存儲(chǔ)器中讀取16位的半字?jǐn)?shù)據(jù)到通用寄存器,,然后對(duì)數(shù)據(jù)進(jìn)行處理。當(dāng)程序計(jì)數(shù)器PC作為目的寄存器時(shí),,指令從存儲(chǔ)器中讀取的字?jǐn)?shù)據(jù)被當(dāng)作目的地址,,從而可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn)。
指令示例:
LDRH R0,,[R1] ,;將存儲(chǔ)器地址為R1的半字?jǐn)?shù)據(jù)讀入寄存器R0,并將R0的高16位清零,。
LDRH R0,,[R1,#8] ,;將存儲(chǔ)器地址為R1+8的半字?jǐn)?shù)據(jù)讀入寄存器R0,,并將R0的高16位清零。
LDRH R0,,[R1,,R2] ;將存儲(chǔ)器地址為R1+R2的半字?jǐn)?shù)據(jù)讀入寄存器R0,,并將R0的高16位清零,。
4、STR指令
STR指令的格式為:
STR{條件} 源寄存器,,<存儲(chǔ)器地址>
STR指令用于從源寄存器中將一個(gè)32位的字?jǐn)?shù)據(jù)傳送到存儲(chǔ)器中,。該指令在程序設(shè)計(jì)中比較常用,且尋址方式靈活多樣,,使用方式可參考指令LDR,。
指令示例:
STR R0,[R1],,#8 ,;將R0中的字?jǐn)?shù)據(jù)寫入以R1為地址的存儲(chǔ)器中,并將新地址R1+8寫入R1,。
STR R0,,[R1,#8] ;將R0中的字?jǐn)?shù)據(jù)寫入以R1+8為地址的存儲(chǔ)器中,。
5,、STRB指令
STRB指令的格式為:
STR{條件}B 源寄存器,<存儲(chǔ)器地址>
STRB指令用于從源寄存器中將一個(gè)8位的字節(jié)數(shù)據(jù)傳送到存儲(chǔ)器中,。該字節(jié)數(shù)據(jù)為源寄存器中的低8位,。
指令示例:
STRB R0,[R1] ,;將寄存器R0中的字節(jié)數(shù)據(jù)寫入以R1為地址的存儲(chǔ)器中。
STRB R0,,[R1,,#8] ;將寄存器R0中的字節(jié)數(shù)據(jù)寫入以R1+8為地址的存儲(chǔ)器中,。
6,、STRH指令
STRH指令的格式為:
STR{條件}H 源寄存器,<存儲(chǔ)器地址>
STRH指令用于從源寄存器中將一個(gè)16位的半字?jǐn)?shù)據(jù)傳送到存儲(chǔ)器中,。該半字?jǐn)?shù)據(jù)為源寄存器中的低16位,。
指令示例:
STRH R0,[R1] ,;將寄存器R0中的半字?jǐn)?shù)據(jù)寫入以R1為地址的存儲(chǔ)器中,。
STRH R0,[R1,,#8] ,;將寄存器R0中的半字?jǐn)?shù)據(jù)寫入以R1+8為地址的存儲(chǔ)器中。
3.3.6, 批量數(shù)據(jù)加載/存儲(chǔ)指令
ARM微處理器所支持批量數(shù)據(jù)加載/存儲(chǔ)指令可以一次在一片連續(xù)的存儲(chǔ)器單元和多個(gè)寄存器之間傳送數(shù)據(jù),,批量加載指令用于將一片連續(xù)的存儲(chǔ)器中的數(shù)據(jù)傳送到多個(gè)寄存器,,批量數(shù)據(jù)存儲(chǔ)指令則完成相反的操作。常用的加載存儲(chǔ)指令如下:
— LDM 批量數(shù)據(jù)加載指令
— STM 批量數(shù)據(jù)存儲(chǔ)指令
LDM(或STM)指令
LDM(或STM)指令的格式為:
LDM(或STM){條件}{類型} 基址寄存器{,!},,寄存器列表{∧}
LDM(或STM)指令用于從由基址寄存器所指示的一片連續(xù)存儲(chǔ)器到寄存器列表所指示的多個(gè)寄存器之間傳送數(shù)據(jù),該指令的常見用途是將多個(gè)寄存器的內(nèi)容入?;虺鰲?。其中,{類型}為以下幾種情況:
IA 每次傳送后地址加1,;
IB 每次傳送前地址加1,;
DA 每次傳送后地址減1;
DB 每次傳送前地址減1,;
FD 滿遞減堆棧,;
ED 空遞減堆棧;
FA 滿遞增堆棧,;
EA 空遞增堆棧,;
{,!}為可選后綴,若選用該后綴,,則當(dāng)數(shù)據(jù)傳送完畢之后,,將最后的地址寫入基址寄存器,否則基址寄存器的內(nèi)容不改變,。
基址寄存器不允許為R15,,寄存器列表可以為R0~R15的任意組合。
{∧}為可選后綴,,當(dāng)指令為LDM且寄存器列表中包含R15,,選用該后綴時(shí)表示:除了正常的數(shù)據(jù)傳送之外,還將SPSR復(fù)制到CPSR,。同時(shí),,該后綴還表示傳入或傳出的是用戶模式下的寄存器,而不是當(dāng)前模式下的寄存器,。
指令示例:
STMFD R13!,,{R0,R4-R12,,LR} ,;將寄存器列表中的寄存器(R0,R4到R12,,LR)存入堆棧,。
LDMFD R13!,{R0,,R4-R12,,PC} ;將堆棧內(nèi)容恢復(fù)到寄存器(R0,,R4到R12,,LR)。
3.3.7 數(shù)據(jù)交換指令
ARM微處理器所支持?jǐn)?shù)據(jù)交換指令能在存儲(chǔ)器和寄存器之間交換數(shù)據(jù),。數(shù)據(jù)交換指令有如下兩條:
— SWP 字?jǐn)?shù)據(jù)交換指令
— SWPB 字節(jié)數(shù)據(jù)交換指令
1,、SWP指令
SWP指令的格式為:
SWP{條件} 目的寄存器,源寄存器1,,[源寄存器2]
SWP指令用于將源寄存器2所指向的存儲(chǔ)器中的字?jǐn)?shù)據(jù)傳送到目的寄存器中,,同時(shí)將源寄存器1中的字?jǐn)?shù)據(jù)傳送到源寄存器2所指向的存儲(chǔ)器中。顯然,,當(dāng)源寄存器1和目的寄存器為同一個(gè)寄存器時(shí),,指令交換該寄存器和存儲(chǔ)器的內(nèi)容。
指令示例:
SWP R0,R1,,[R2] ,;將R2所指向的存儲(chǔ)器中的字?jǐn)?shù)據(jù)傳送到R0,同時(shí)將R1中的字?jǐn)?shù)據(jù)傳送到R2所指向的存儲(chǔ)單元,。
SWP R0,,R0,[R1] ,;該指令完成將R1所指向的存儲(chǔ)器中的字?jǐn)?shù)據(jù)與R0中的字?jǐn)?shù)據(jù)交換,。
2、SWPB指令
SWPB指令的格式為:
SWP{條件}B 目的寄存器,,源寄存器1,,[源寄存器2]
SWPB指令用于將源寄存器2所指向的存儲(chǔ)器中的字節(jié)數(shù)據(jù)傳送到目的寄存器中,目的寄存器的高24清零,,同時(shí)將源寄存器1中的字節(jié)數(shù)據(jù)傳送到源寄存器2所指向的存儲(chǔ)器中。顯然,,當(dāng)源寄存器1和目的寄存器為同一個(gè)寄存器時(shí),,指令交換該寄存器和存儲(chǔ)器的內(nèi)容。
指令示例:
SWPB R0,,R1,,[R2] ;將R2所指向的存儲(chǔ)器中的字節(jié)數(shù)據(jù)傳送到R0,,R0的高24位清零,,同時(shí)將R1中的低8位數(shù)據(jù)傳送到R2所指向的存儲(chǔ)單元。
SWPB R0,,R0,,[R1] ;該指令完成將R1所指向的存儲(chǔ)器中的字節(jié)數(shù)據(jù)與R0中的低8位數(shù)據(jù)交換,。
3.3.8 移位指令(操作)
ARM微處理器內(nèi)嵌的桶型移位器(Barrel Shifter),,支持?jǐn)?shù)據(jù)的各種移位操作,移位操作在ARM指令集中不作為單獨(dú)的指令使用,,它只能作為指令格式中是一個(gè)字段,,在匯編語言中表示為指令中的選項(xiàng)。例如,,數(shù)據(jù)處理指令的第二個(gè)操作數(shù)為寄存器時(shí),,就可以加入移位操作選項(xiàng)對(duì)它進(jìn)行各種移位操作。移位操作包括如下6種類型,,ASL和LSL是等價(jià)的,,可以自由互換:
— LSL 邏輯左移
— ASL 算術(shù)左移
— LSR 邏輯右移
— ASR 算術(shù)右移
— ROR 循環(huán)右移
— RRX 帶擴(kuò)展的循環(huán)右移
1、LSL(或ASL)操作
LSL(或ASL)操作的格式為:
通用寄存器,LSL(或ASL) 操作數(shù)
LSL(或ASL)可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行邏輯(或算術(shù))的左移操作,,按操作數(shù)所指定的數(shù)量向左移位,,低位用零來填充。其中,,操作數(shù)可以是通用寄存器,,也可以是立即數(shù)(0~31)。
操作示例:
MOV R0, R1, LSL#2 ,;將R1中的內(nèi)容左移兩位后傳送到R0中,。
2、LSR操作
LSR操作的格式為:
通用寄存器,,LSR 操作數(shù)
LSR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,,按操作數(shù)所指定的數(shù)量向右移位,左端用零來填充,。其中,,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0~31),。
操作示例:
MOV R0, R1, LSR#2 ,;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用零來填充,。
3,、ASR操作
ASR操作的格式為:
通用寄存器,ASR 操作數(shù)
ASR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,,按操作數(shù)所指定的數(shù)量向右移位,,左端用第31位的值來填充。其中,,操作數(shù)可以是通用寄存器,,也可以是立即數(shù)(0~31)。
操作示例:
MOV R0, R1, ASR#2 ,;將R1中的內(nèi)容右移兩位后傳送到R0中,,左端用第31位的值來填充。
4,、ROR操作
ROR操作的格式為:
通用寄存器,,ROR 操作數(shù)
ROR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行循環(huán)右移的操作,按操作數(shù)所指定的數(shù)量向右循環(huán)移位,,左端用右端移出的位來填充,。其中,操作數(shù)可以是通用寄存器,,也可以是立即數(shù)(0~31),。顯然,,當(dāng)進(jìn)行32位的循環(huán)右移操作時(shí),通用寄存器中的值不改變,。
操作示例:
MOV R0, R1, ROR#2 ,;將R1中的內(nèi)容循環(huán)右移兩位后傳送到R0中。
5,、RRX操作
RRX操作的格式為:
通用寄存器,,RRX 操作數(shù)
RRX可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行帶擴(kuò)展的循環(huán)右移的操作,按操作數(shù)所指定的數(shù)量向右循環(huán)移位,,左端用進(jìn)位標(biāo)志位C來填充,。其中,操作數(shù)可以是通用寄存器,,也可以是立即數(shù)(0~31),。
操作示例:
MOV R0, R1, RRX#2 ;將R1中的內(nèi)容進(jìn)行帶擴(kuò)展的循環(huán)右移兩位后傳送到R0中,。
3.3.9 協(xié)處理器指令
ARM微處理器可支持多達(dá)16個(gè)協(xié)處理器,,用于各種協(xié)處理操作,在程序執(zhí)行的過程中,,每個(gè)協(xié)處理器只執(zhí)行針對(duì)自身的協(xié)處理指令,,忽略ARM處理器和其他協(xié)處理器的指令。
ARM的協(xié)處理器指令主要用于ARM處理器初始化ARM協(xié)處理器的數(shù)據(jù)處理操作,,以及在ARM處理器的寄存器和協(xié)處理器的寄存器之間傳送數(shù)據(jù),和在ARM協(xié)處理器的寄存器和存儲(chǔ)器之間傳送數(shù)據(jù),。ARM協(xié)處理器指令包括以下5條:
— CDP 協(xié)處理器數(shù)操作指令
— LDC 協(xié)處理器數(shù)據(jù)加載指令
— STC 協(xié)處理器數(shù)據(jù)存儲(chǔ)指令
— MCR ARM處理器寄存器到協(xié)處理器寄存器的數(shù)據(jù)傳送指令
— MRC 協(xié)處理器寄存器到ARM處理器寄存器的數(shù)據(jù)傳送指令
1,、CDP指令
CDP指令的格式為:
CDP{條件} 協(xié)處理器編碼,協(xié)處理器操作碼1,,目的寄存器,,源寄存器1,源寄存器2,,協(xié)處理器操作碼2,。
CDP指令用于ARM處理器通知ARM協(xié)處理器執(zhí)行特定的操作,若協(xié)處理器不能成功完成特定的操作,則產(chǎn)生未定義指令異常,。其中協(xié)處理器操作碼1和協(xié)處理器操作碼2為協(xié)處理器將要執(zhí)行的操作,,目的寄存器和源寄存器均為協(xié)處理器的寄存器,指令不涉及ARM處理器的寄存器和存儲(chǔ)器,。
指令示例:
CDP P3,,2,C12,,C10,,C3,,4 ;該指令完成協(xié)處理器P3的初始化
2,、LDC指令
LDC指令的格式為:
LDC{條件}{L} 協(xié)處理器編碼,目的寄存器,,[源寄存器]
LDC指令用于將源寄存器所指向的存儲(chǔ)器中的字?jǐn)?shù)據(jù)傳送到目的寄存器中,若協(xié)處理器不能成功完成傳送操作,,則產(chǎn)生未定義指令異常,。其中,{L}選項(xiàng)表示指令為長讀取操作,,如用于雙精度數(shù)據(jù)的傳輸,。
指令示例:
LDC P3,C4,,[R0] ,;將ARM處理器的寄存器R0所指向的存儲(chǔ)器中的字?jǐn)?shù)據(jù)傳送到協(xié)處理器P3的寄存器C4中。
3,、STC指令
STC指令的格式為:
STC{條件}{L} 協(xié)處理器編碼,源寄存器,,[目的寄存器]
STC指令用于將源寄存器中的字?jǐn)?shù)據(jù)傳送到目的寄存器所指向的存儲(chǔ)器中,若協(xié)處理器不能成功完成傳送操作,,則產(chǎn)生未定義指令異常,。其中,{L}選項(xiàng)表示指令為長讀取操作,,如用于雙精度數(shù)據(jù)的傳輸,。
指令示例:
STC P3,C4,,[R0] ,;將協(xié)處理器P3的寄存器C4中的字?jǐn)?shù)據(jù)傳送到ARM處理器的寄存器R0所指向的存儲(chǔ)器中。
4,、MCR指令
MCR指令的格式為:
MCR{條件} 協(xié)處理器編碼,,協(xié)處理器操作碼1,源寄存器,,目的寄存器1,,目的寄存器2,協(xié)處理器操作碼2,。
MCR指令用于將ARM處理器寄存器中的數(shù)據(jù)傳送到協(xié)處理器寄存器中,若協(xié)處理器不能成功完成操作,,則產(chǎn)生未定義指令異常。其中協(xié)處理器操作碼1和協(xié)處理器操作碼2為協(xié)處理器將要執(zhí)行的操作,,源寄存器為ARM處理器的寄存器,,目的寄存器1和目的寄存器2均為協(xié)處理器的寄存器。
指令示例:
MCR P3,,3,,R0,,C4,C5,,6 ,;該指令將ARM處理器寄存器R0中的數(shù)據(jù)傳送到協(xié)處理器P3的寄存器C4和C5中。
5,、MRC指令
MRC指令的格式為:
MRC{條件} 協(xié)處理器編碼,,協(xié)處理器操作碼1,目的寄存器,,源寄存器1,,源寄存器2,協(xié)處理器操作碼2,。
MRC指令用于將協(xié)處理器寄存器中的數(shù)據(jù)傳送到ARM處理器寄存器中,若協(xié)處理器不能成功完成操作,,則產(chǎn)生未定義指令異常。其中協(xié)處理器操作碼1和協(xié)處理器操作碼2為協(xié)處理器將要執(zhí)行的操作,,目的寄存器為ARM處理器的寄存器,,源寄存器1和源寄存器2均為協(xié)處理器的寄存器。
指令示例:
MRC P3,,3,,R0,C4,,C5,,6 ;該指令將協(xié)處理器P3的寄存器中的數(shù)據(jù)傳送到ARM處理器寄存器中,。
3.3.10 異常產(chǎn)生指令
ARM微處理器所支持的異常指令有如下兩條:
— SWI 軟件中斷指令
— BKPT 斷點(diǎn)中斷指令
1,、SWI指令
SWI指令的格式為:
SWI{條件} 24位的立即數(shù)
SWI指令用于產(chǎn)生軟件中斷,以便用戶程序能調(diào)用操作系統(tǒng)的系統(tǒng)例程,。操作系統(tǒng)在SWI的異常處理程序中提供相應(yīng)的系統(tǒng)服務(wù),指令中24位的立即數(shù)指定用戶程序調(diào)用系統(tǒng)例程的類型,,相關(guān)參數(shù)通過通用寄存器傳遞,,當(dāng)指令中24位的立即數(shù)被忽略時(shí),用戶程序調(diào)用系統(tǒng)例程的類型由通用寄存器R0的內(nèi)容決定,,同時(shí),,參數(shù)通過其他通用寄存器傳遞。
指令示例:
SWI 0x02 ,;該指令調(diào)用操作系統(tǒng)編號(hào)位02的系統(tǒng)例程,。
2、BKPT指令
BKPT指令的格式為:
BKPT 16位的立即數(shù)
BKPT指令產(chǎn)生軟件斷點(diǎn)中斷,,可用于程序的調(diào)試,。
3.4 Thumb指令及應(yīng)用
為兼容數(shù)據(jù)總線寬度為16位的應(yīng)用系統(tǒng),,ARM體系結(jié)構(gòu)除了支持執(zhí)行效率很高的32位ARM指令集以外,同時(shí)支持16位的Thumb指令集,。Thumb指令集是ARM指令集的一個(gè)子集,,允許指令編碼為16位的長度。與等價(jià)的32位代碼相比較,,Thumb指令集在保留32代碼優(yōu)勢(shì)的同時(shí),,大大的節(jié)省了系統(tǒng)的存儲(chǔ)空間。
所有的Thumb指令都有對(duì)應(yīng)的ARM指令,,而且Thumb的編程模型也對(duì)應(yīng)于ARM的編程模型,,在應(yīng)用程序的編寫過程中,只要遵循一定調(diào)用的規(guī)則,,Thumb子程序和ARM子程序就可以互相調(diào)用,。當(dāng)處理器在執(zhí)行ARM程序段時(shí),稱ARM處理器處于ARM工作狀態(tài),,當(dāng)處理器在執(zhí)行Thumb程序段時(shí),,稱ARM處理器處于Thumb工作狀態(tài)。
與ARM指令集相比較,,Thumb指令集中的數(shù)據(jù)處理指令的操作數(shù)仍然是32位,,指令地址也為32位,但Thumb指令集為實(shí)現(xiàn)16位的指令長度,,舍棄了ARM指令集的一些特性,,如大多數(shù)的Thumb指令是無條件執(zhí)行的,而幾乎所有的ARM指令都是有條件執(zhí)行的,;大多數(shù)的Thumb數(shù)據(jù)處理指令的目的寄存器與其中一個(gè)源寄存器相同,。
由于Thumb指令的長度為16位,即只用ARM指令一半的位數(shù)來實(shí)現(xiàn)同樣的功能,,所以,,要實(shí)現(xiàn)特定的程序功能,所需的Thumb指令的條數(shù)較ARM指令多,。在一般的情況下,,Thumb指令與ARM指令的時(shí)間效率和空間效率關(guān)系為:
— Thumb代碼所需的存儲(chǔ)空間約為ARM代碼的60%~70%
— Thumb代碼使用的指令數(shù)比ARM代碼多約30%~40%
— 若使用32位的存儲(chǔ)器,ARM代碼比Thumb代碼快約40%
— 若使用16位的存儲(chǔ)器,,Thumb代碼比ARM代碼快約40%~50%
— 與ARM代碼相比較,,使用Thumb代碼,存儲(chǔ)器的功耗會(huì)降低約30%
顯然,,ARM指令集和Thumb指令集各有其優(yōu)點(diǎn),,若對(duì)系統(tǒng)的性能有較高要求,應(yīng)使用32位的存儲(chǔ)系統(tǒng)和ARM指令集,,若對(duì)系統(tǒng)的成本及功耗有較高要求,,則應(yīng)使用16位的存儲(chǔ)系統(tǒng)和Thumb指令集,。當(dāng)然,若兩者結(jié)合使用,,充分發(fā)揮其各自的優(yōu)點(diǎn),,會(huì)取得更好的效果。
3.5 本章小節(jié)
本章系統(tǒng)的介紹了ARM指令集中的基本指令,,以及各指令的應(yīng)用場合及方法,,由基本指令還可以派生出一些新的指令,但使用方法與基本指令類似,。與常見的如X86體系結(jié)構(gòu)的匯編指令相比較,,ARM指令系統(tǒng)無論是從指令集本身,還是從尋址方式上,,都相對(duì)復(fù)雜一些,。
Thumb指令集作為ARM指令集的一個(gè)子集,其使用方法與ARM指令集類似,,在此未作詳細(xì)的描述,,但這并不意味著Thumb指令集不如ARM指令集重要,事實(shí)上,,他們各自有其自己的應(yīng)用場合,。