ARM處理器的指令集可以分為跳轉(zhuǎn)指令、數(shù)據(jù)處理指令、程序狀態(tài)寄存器(PSR)處理指令、加載/存儲(chǔ)指令、協(xié)處理器指令和異常產(chǎn)生指令6大指令。
一、跳轉(zhuǎn)指令
跳轉(zhuǎn)指令用于實(shí)現(xiàn)程序流程的跳轉(zhuǎn),在ARM程序中有以下兩種方法可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn)。
Ⅰ.使用專門(mén)的跳轉(zhuǎn)指令;
?、?直接向程序計(jì)數(shù)器PC寫(xiě)入跳轉(zhuǎn)地址值,通過(guò)向程序計(jì)數(shù)器PC寫(xiě)入跳轉(zhuǎn)地址值,可以實(shí)現(xiàn)在4GB的地址空間中的任意跳轉(zhuǎn),在跳轉(zhuǎn)之前結(jié)合使用MOV LR,PC等類似指令,可以保存將來(lái)的返回地址值,從而實(shí)現(xiàn)在4GB連續(xù)的線性地址空間的子程序調(diào)用。
ARM指令集中的跳轉(zhuǎn)指令可以完成從當(dāng)前指令向前或向后的32MB的地址空間的跳轉(zhuǎn),包括以下4條指令:
1、B指令
B指令的格式為:
B{條件} 目標(biāo)地址
B指令是最簡(jiǎn)單的跳轉(zhuǎn)指令。一旦遇到一個(gè)B指令,ARM處理器將立即跳轉(zhuǎn)到給定的目標(biāo)地址,從那里繼續(xù)執(zhí)行。注意存儲(chǔ)在跳轉(zhuǎn)指令中的實(shí)際值是相對(duì)當(dāng)前PC 值的一個(gè)偏移量,而不是一個(gè)絕對(duì)地址,它的值由匯編器來(lái)計(jì)算(參考尋址方式中的相對(duì)尋址)。它是24位有符號(hào)數(shù),左移兩位后有符號(hào)擴(kuò)展為32 位,表示的有效偏移為26 位(前后32MB的地址空間)。以下指令:
B Label ;程序無(wú)條件跳轉(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)容,因此,可以通過(guò)將R14的內(nèi)容重新加載到PC中,來(lái)返回到跳轉(zhuǎn)指令之后的那個(gè) 指令處執(zhí)行。該指令是實(shí)現(xiàn)子程序調(diào)用的一個(gè)基本但常用的手段。
以 下指令:
BL Label ;當(dāng)程序無(wú)條件跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行時(shí),同時(shí)將當(dāng)前的 PC值保存到
??;R14(LR)中
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í),可以通過(guò)BLX指令實(shí)現(xiàn)子程序的調(diào)用和處理器工作狀態(tài)的切換。同時(shí),子程 序的返回可以通過(guò)將寄存器R14值復(fù)制到PC中來(lái)完成。
4、BX指令
BX指令的格式為:
BX{條件} 目標(biāo)地址
BX指令跳轉(zhuǎn)到指令中所指定的目標(biāo)地址,目標(biāo)地址處的指令既可以是ARM指令,也可以是Thumb指令。
二、數(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ù)處理指令共以下16條。
1、MOV指令(傳送)
MOV指令的格式為:
MOV{條件}{S} 目的寄存器,源操作數(shù)
MOV指令可完成從另一個(gè)寄存器、被移位的寄存器或?qū)⒁粋€(gè)立即數(shù)加載到目的寄存器。其中S選項(xiàng)決定指令的操作是否影響CPSR中條件標(biāo)志位的值,當(dāng)沒(méi)有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)沒(méi)有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)
?。恢疚?br/> CMP R1,#100 ;將寄存器R1的值與立即數(shù)100相減,并根 據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
4、CMN指令(負(fù)數(shù)比較)
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指令(測(cè)試)
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是要測(cè)試的數(shù) 據(jù),而操作數(shù)2是一個(gè)位掩碼,該指令一般用來(lái)檢測(cè)是否設(shè)置了特定的位。
指令示例:
TST R1,#%1 ;用于測(cè)試在寄存器R1中是否設(shè)置了最低位(%表 示二進(jìn)制數(shù))
TST R1,#0xffe ;將寄存器R1的值與立即數(shù)0xffe按位與,并根據(jù) 結(jié)果設(shè)置CPSR
??;的標(biāo)志位
6、TEQ指令(測(cè)試相等)
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指令(帶進(jìn)位相加)
ADC指令的格式為:
ADC{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2
ADC指令用于把兩個(gè)操作數(shù)相加,再加上CPSR中的C條件標(biāo)志位的值,并將結(jié)果存放到目的寄存器中。它使用一個(gè)進(jìn)位標(biāo)志位,這樣就可以做比32位大的數(shù) 的加法,注意不要忘記設(shè)置S后綴來(lái)更改進(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ù)或無(wú)符號(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、~~~~C指令
~~~~C指令的格式為:
~~~~C{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2
~~~~C指令用于把操作數(shù)1減去操作數(shù)2,再減去CPSR中的C條件標(biāo)志位的反碼,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以 是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。該指令使用進(jìn)位標(biāo)志來(lái)表示借位,這樣就可以做大于32位的減法,注意不要忘記設(shè)置S后綴來(lái)更改進(jìn)位標(biāo)志。該指令可用于有符號(hào)數(shù)或無(wú)符號(hào)數(shù)的減法運(yùn)算。
指令示例:
SUBS R0,R1,R2 ;R0 = R1 - R2 - !C,并根據(jù)結(jié)果設(shè)置CPSR的進(jìn)位標(biāo)志位
11、R~~~~指令
R~~~~指令的格式為:
R~~~~{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2
R~~~~指令稱為逆向減法指令,用于把操作數(shù)2減去操作數(shù)1,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位 的寄存器,或一個(gè)立即數(shù)。該指令可用于有符號(hào)數(shù)或無(wú)符號(hào)數(shù)的減法運(yùn)算。
指令示例:
R~~~~ R0,R1,R2 ; R0 = R2 – R1
R~~~~ R0,R1,#256 ; R0 = 256 – R1
R~~~~ R0,R2,R3,LSL#1 ; R0 = (R3 << 1) - R2
12、RSC指令(反向帶進(jìn)位減)
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)志來(lái)表示借位,這樣就可以做大于32位的減法,注意不要忘記設(shè)置S后綴來(lái)更改進(jìn)位標(biāo)志。該指令可用于有符號(hào)數(shù)或 無(wú)符號(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,其余的位保持不變。
三、乘法指令與乘加指令
ARM 微處理器支持的乘法指令與乘加指令共有6條,可分為運(yùn)算結(jié)果為32位和運(yùn)算結(jié)果為64位兩類,與前面的數(shù)據(jù)處理指令不同,指令中的所有操作數(shù)、目的寄存器 必須為通用寄存器,不能對(duì)操作數(shù)使用立即數(shù)或被移位的寄存器,同時(shí),目的寄存器和操作數(shù)1必須是不同的寄存器。
乘法指令與乘加指令共有以下6條:
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ù)或無(wú)符號(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ù)或無(wú)符號(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位
?。籖1 = (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位的無(wú)符號(hào)數(shù)。
指令示例:
UMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32位
??;R1 = (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位的無(wú)符號(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
四、程序狀態(tài)寄存器訪問(wèn)指令
1、MRS指令
MRS指令的格式為:
MRS{條件} 通用寄存器 程序狀態(tài)寄存器(CPSR或SPSR)
MRS指令用于將程序狀態(tài)寄存器的內(nèi)容傳送到通用寄存器中。該指令一般用在以下兩種情況:
Ⅰ.當(dāng)需要改變程序狀態(tài)寄存器的內(nèi)容時(shí),可用MRS將程序狀態(tài)寄存器的內(nèi)容讀入通用寄存器,修改后再寫(xiě)回程序狀態(tài)寄存器。
Ⅱ.當(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]為條件位域,用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中的控制位域
五、加載/存儲(chǔ)指令。ARM微處理器支持加載/存儲(chǔ)指令用于在寄存器和存儲(chǔ)器之間傳送數(shù)據(jù),加載指令用于將存儲(chǔ)器中的數(shù)據(jù)傳送到寄存器,存儲(chǔ) 指令則完成相反的操作。常用的加載存儲(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寫(xiě)入R1。
LDR R0,[R1,#8] ! ;將存儲(chǔ)器地址為R1+8的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址 R1
??;+8寫(xiě)入R1。
LDR R0,[R1],R2 ;將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址 R1+
??;R2寫(xiě)入R1。
LDR R0,[R1,R2,LSL#2]! ;將存儲(chǔ)器地址為R1+R2×4的字?jǐn)?shù)據(jù)讀入寄存器R0,并
;將新地址R1+R2×4寫(xiě)入R1。
LDR R0,[R1],R2,LSL#2 ;將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入 寄存器R0,并將新地
??;址R1+R2×4寫(xiě)入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的
?。桓?4位清零。
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ù)寫(xiě)入以R1為地址的存儲(chǔ)器中,并 將新地址
??;R1+8寫(xiě)入R1。
STR R0,[R1,#8] ;將R0中的字?jǐn)?shù)據(jù)寫(xiě)入以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ù)寫(xiě)入以R1為地 址的存儲(chǔ)器中。
STRB R0,[R1,#8] ;將寄存器R0中的字節(jié)數(shù)據(jù)寫(xiě)入以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ù)寫(xiě)入以R1為地址的 存儲(chǔ)器中。
STRH R0,[R1,#8] ;將寄存器R0中的半字?jǐn)?shù)據(jù)寫(xiě)入以R1+8 為地址的存儲(chǔ)器中。
六、批量數(shù)據(jù)加載/存儲(chǔ)指令。
ARM微處理器所支持批量數(shù)據(jù)加載/存儲(chǔ)指令可以一次在一片連續(xù)的存儲(chǔ)器單元和多個(gè)寄存器之間傳送數(shù)據(jù),批量加載指令 用于將一片連續(xù)的存儲(chǔ)器中的數(shù)據(jù)傳送到多個(gè)寄存器,批量數(shù)據(jù)存儲(chǔ)指令則完成相反的操作。常用的加載存儲(chǔ)指令如下:LDM(或STM)指令
LDM(或STM)指令的格式為:
LDM(或STM){條件}{類型} 基址寄存器{!},寄存器列表{∧}
LDM(或STM)指令用于從由基址寄存器所指示的一片連續(xù)存儲(chǔ)器到寄存器列表所指示的多個(gè)寄存器之間傳送數(shù)據(jù),該指令的常見(jiàn)用途是將多個(gè)寄存器的內(nèi)容入?;虺鰲!F渲?,{類型}為 以下幾種情況:
IA 每次傳送后地址加1;
IB 每次傳送前地址加1;
DA 每次傳送后地址減1;
DB 每次傳送前地址減1;
FD 滿遞減堆棧;
ED 空遞減堆棧;
FA 滿遞增堆棧;
EA 空遞增堆棧;
{!}為可選后綴,若選用該后綴,則當(dāng)數(shù)據(jù) 傳送完畢之后,將最后的地址寫(xiě)入基址寄存器,否則基址寄存器的內(nèi)容不改變。
基址寄存器不允許為R15,寄存器列表可以為R0~R15的任意組合。
{∧}為可選后綴,當(dāng)指令為L(zhǎng)DM且寄存器列表中包含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)。
七、數(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中的數(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ù)交換。