ARM微處理器的指令集概述二——ARM應(yīng)用系統(tǒng)開發(fā)詳解筆記
一 跳轉(zhuǎn)指令
跳轉(zhuǎn)指令用于實現(xiàn)程序流程的跳轉(zhuǎn),在 ARM 程序中有兩種方法可以實現(xiàn)程序流程的跳轉(zhuǎn):
— 使用專門的跳轉(zhuǎn)指令。
— 直接向程序計數(shù)器 PC 寫入跳轉(zhuǎn)地址值。
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)指令
B
B{條件} 目標(biāo)地址B指令是最簡單的跳轉(zhuǎn)指令。注意存儲在跳轉(zhuǎn)指令中的實際值是相對當(dāng)前PC值的一個偏移量,而不是一個絕對地址,它的值由匯編器來計算(參考尋址方式中的相對尋址) 它是 24 位有符號數(shù),左移兩位后有符號擴展為 32 位,表示的有效偏移為 26 位(前后 32MB的地址空間)。
BL 指令
BL{條件} 目標(biāo)地址
BL 是另一個跳轉(zhuǎn)指令,但跳轉(zhuǎn)之前,會在寄存器R14 中保存PC的當(dāng)前內(nèi)容,因此,可以通過將R14 的內(nèi)容重新加載到PC中,來返回到跳轉(zhuǎn)指令之后的那個指令處執(zhí)行。該指令是實現(xiàn)子程序調(diào)用的一個基本但常用的手段。例:
BL Label ;當(dāng)程序無條件跳轉(zhuǎn)到標(biāo)號 Label 處執(zhí)行時,同時將當(dāng)前的 PC 值保存到 R14 中。
BLX 指令
BLX指令從ARM指令集跳轉(zhuǎn)到指令中所指定的目標(biāo)地址,并將處理器的工作狀態(tài)有ARM狀態(tài)切換到Thumb狀態(tài)。該指令同時將PC的當(dāng)前內(nèi)容保存到寄存器R14 中。
BX 指令
BX指令跳轉(zhuǎn)到指令中所指定的目標(biāo)地址,目標(biāo)地址處的指令既可以是ARM指令,也可以是Thumb指令。
二 數(shù)據(jù)處理指令
數(shù)據(jù)處理指令可分為數(shù)據(jù)傳送指令、算術(shù)邏輯運算指令和比較指令等。數(shù)據(jù)處理指令包括:MOV 數(shù)據(jù)傳送指令、MVN 數(shù)據(jù)取反傳送指令、CMP 比較指令、CMN 反值比較指令、 TST 位測試指令、 TEQ 相等測試指令、 ADD 加法指令、 ADC 帶進位加法指令、 SUB 減法指令、 SBC 帶借位減法指令、 RSB 逆向減法指令、 RSC 帶借位的逆向減法指令、 AND 邏輯與指令、 ORR 邏輯或指令、 EOR 邏輯異或指令、 BIC 位清除指令。
MOV 指令
MOV{條件}{S} 目的寄存器,源操作數(shù)
MOV 指令將源操作數(shù)加載到目的寄存器。其中 S 選項決定指令的操作是否影響 CPSR 中條件標(biāo)志位的值,當(dāng)沒有 S 時指令不更新 CPSR中條件標(biāo)志位的值。例:
MOV R1,R0,LSL#3 ; 將寄存器 R0 的值左移 3 位后傳送到 R1。
MVN 指令
MVN{條件}{S} 目的寄存器,源操作數(shù)
MOV 指令不同之處是在傳送之前將源操作數(shù)按位被取反。例:
MVN R0, #0; 將立即數(shù) 0 取反傳送到寄存器 R0 中,完成后 R0=-1。
CMP 指令
CMP{條件} 操作數(shù) 1,操作數(shù) 2比較操作數(shù)1和操作數(shù)2,更新CSPR不保存結(jié)果。標(biāo)志位表示的是操作數(shù) 1 與操作數(shù) 2 的關(guān)系(大、小、相等)。例如,當(dāng)操作數(shù) 1 大于操作操作數(shù) 2,則此后的有GT 后綴的指令將可以執(zhí)行。例:
CMP R1,#100 ;將寄存器 R1 的值與立即數(shù) 100 相減,并根據(jù)結(jié)果設(shè)置 CPSR 的標(biāo)志位
CMN 指令
CMN{條件} 操作數(shù) 1,操作數(shù) 2
實際完成操作數(shù) 1 和操作數(shù) 2 相加,并根據(jù)結(jié)果更改條件標(biāo)志位。例:
CMN R1,R0 ;將寄存器 R1 的值與寄存器 R0 的值相加,并根據(jù)結(jié)果設(shè)置 CPSR
TST 指令
TST{條件} 操作數(shù) 1,操作數(shù) 2
TST指令用于把一個寄存器的內(nèi)容和另一個寄存器的內(nèi)容或立即數(shù)進行按位的與運算,并根據(jù)運算結(jié)果更新CPSR中條件標(biāo)志位的值。操作數(shù) 1 是要測試的數(shù)據(jù),而操作數(shù) 2 是一個位掩碼,該指令一般用來檢測是否設(shè)置了特定的位。例:
TST R1,#0xffe ;將寄存器 R1 的值與立即數(shù) 0xffe 按位與,并根據(jù)結(jié)果設(shè)置 CPSR
TEQ 指令
TEQ{條件} 操作數(shù) 1,操作數(shù) 2
TEQ指令用于 把一個寄存器的內(nèi)容和另一個寄存器的內(nèi)容或立即數(shù)進行按位的異或運算,并根據(jù)運算結(jié)果更新CPSR中條件標(biāo)志位的值。該指令通常用于比較操作數(shù) 1 和操作數(shù)2 是否相等。例:
TEQ R1,R2 ;將寄存器 R1 的值與寄存器 R2 的值按位異或,并根據(jù)結(jié)果設(shè)置 CPSR
ADD 指令
ADD{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
ADD R0,R2,R3,LSL#1 ; R0 = R2 + (R3 << 1)
ADC 指令
ADC{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
ADC指令用于把兩個操作數(shù)相加,再加上CPSR中的C條件標(biāo)志位的值,并將結(jié)果存放到目的寄存器中。它使用一個進位標(biāo)志位,這樣就可以做比 32 位大的數(shù)的加法,注意不要忘記設(shè)置S后綴來更改進位標(biāo)志。以下指令序列完成兩個 128 位數(shù)的加法,第一個數(shù)由高到低存放在寄存器 R7~R4,第二個數(shù)由高到低存放在寄存器 R11~R8,運算結(jié)果由高到低存放在寄存器 R3~R0:
ADDS R0,R4,R8 ; 加低端的字
ADCS R1,R5,R9 ; 加第二個字,帶進位
ADCS R2,R6,R10 ; 加第三個字,帶進位
ADC R3,R7,R11; 加第四個字,帶進位
SUB 指令
SUB{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
SUB指令用于把操作數(shù) 1 減去操作數(shù) 2,并將結(jié)果存放到目的寄存器中。
SUB R0,R2,R3,LSL#1 ; R0 = R2 - (R3 << 1)
SBC 指令
SBC{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
SBC指令用于把操作數(shù) 1 減去操作數(shù) 2,再減去CPSR中的C條件標(biāo)志位的反碼,并將結(jié)果存放到目的寄存器中。
SUBS R0,R1,R2 ; R0 = R1 - R2 - !C,并根據(jù)結(jié)果設(shè)置 CPSR 的進位標(biāo)志位
RSB 指令
RSB{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
RSB指令稱為逆向減法指令,用于把操作數(shù) 2 減去操作數(shù) 1,并將結(jié)果存放到目的寄存器中。
RSB R0,R2,R3,LSL#1 ; R0 = (R3 << 1) - R2
RSC 指令
RSC{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
RSC指令用于把操作數(shù) 2 減去操作數(shù) 1,再減去CPSR中的C條件標(biāo)志位的反碼,并將結(jié)果存放到目的寄存器中。
AND 指令
AND{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
AND指令用于在兩個操作數(shù)上進行邏輯與運算,并把結(jié)果放置到目的寄存器中。該指令常用于屏蔽操作數(shù) 1 的某些位。
AND R0,R0,#3 ; 該指令保持 R0 的 0、1 位,其余位清零。
ORR 指令
ORR{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
該指令常用于設(shè)置操作數(shù) 1 的某些位。
EOR 指令
EOR{條件}{S} 目的寄存器,操作數(shù) 1,操作數(shù) 2
該指令常用于反轉(zhuǎn)操作數(shù) 1 的某些位。
三 乘法指令與乘加指令
乘法指令與乘加指令共有以下 6 條:
— MUL 32 位乘法指令
— MLA 32 位乘加指令
— SMULL 64 位有符號數(shù)乘法指令
— SMLAL 64 位有符號數(shù)乘加指令
— UMULL 64 位無符號數(shù)乘法指令
— UMLAL 64 位無符號數(shù)乘加指令
MULS R0,R1,R2 ;R0 = R1 × R2,同時設(shè)置 CPSR 中的相關(guān)條件標(biāo)志位
MLAS R0,R1,R2,R3 ;R0 = R1 × R2 + R3,同時設(shè)置 CPSR 中的相關(guān)條件標(biāo)志位
SMLAL R0,R1,R2,R3;R0 = (R2 × R3)的低 32 位 + R0
;R1 = (R2 × R3)的高 32 位 + R1
;其中,操作數(shù) 1(R2) 和操作數(shù) 2(R3) 均為 32 位的有符號數(shù)。
四 程序狀態(tài)寄存器訪問指令
— MRS 程序狀態(tài)寄存器到通用寄存器的數(shù)據(jù)傳送指令
— MSR 通用寄存器到程序狀態(tài)寄存器的數(shù)據(jù)傳送指令
MRS 指令
MRS{條件}通用寄存器,程序狀態(tài)寄存器(CPSR 或 SPSR) MRS R0,CPSR ;傳送 CPSR 的內(nèi)容到 R0
MRS R0,SPSR ;傳送 SPSR 的內(nèi)容到 R0
MSR 指令
MSR{條件} 程序狀態(tài)寄存器(CPSR 或 SPSR)_<域>,操作數(shù)
MSR 指令用于將操作數(shù)的內(nèi)容傳送到程序狀態(tài)寄存器的特定域中。其中,操作數(shù)可以為通用寄存器或立即數(shù)。<域>用于設(shè)置程序狀態(tài)寄存器中需要操作的位,32 位的程序狀態(tài)寄存器可分為 4 個域:
位[31:24]為條件標(biāo)志位域,用 f 表示;
位[23:16]為狀態(tài)位域,用 s 表示;
位[15:8]為擴展位域,用 x 表示;
位[7:0]為控制位域,用 c 表示;
該指令通常用于恢復(fù)或改變程序狀態(tài)寄存器的內(nèi)容,在使用時,一般要在 MSR 指令中指明將要操作的域。
MSR CPSR_c,R0 ;傳送 R0 的內(nèi)容到 SPSR,但僅僅修改 CPSR 中的控制位域
五 加載/存儲指令
LDR指令LDR{條件} 目的寄存器,<存儲器地址>
LDR R0,[R1,R2] ;將存儲器地址為 R1+R2 的字?jǐn)?shù)據(jù)讀入寄存器 R0。
LDR R0,[R1,#8] ;將存儲器地址為 R1+8 的字?jǐn)?shù)據(jù)讀入寄存器 R0。
LDR R0,[R1,R2] ! ;將存儲器地址為 R1+R2 的字?jǐn)?shù)據(jù)讀入寄存器 R0,并將新地址 R1+R2 寫入 R1。
LDRR0,[R1,#8] ! ;將存儲器地址為 R1+8 的字?jǐn)?shù)據(jù)讀入寄存器 R0,并將新地址 R1+8 寫入 R1。
LDRR0,[R1],R2 ;將存儲器地址為 R1 的字?jǐn)?shù)據(jù)讀入寄存器 R0,并將新地址 R1+R2 寫入 R1。
LDRR0,[R1,R2,LSL#2]! ;將存儲器地址為 R1+R2×4 的字?jǐn)?shù)據(jù)讀入寄存器 R0,并將新地址 R1+R2×4 寫入 R1。
LDRR0,[R1],R2,LSL#2 ;將存儲器地址為 R1 的字?jǐn)?shù)據(jù)讀入寄存器 R0,并將新地址 R1+R2×4 寫入 R1。
帶!號的指令和[]外有寄存器的指令,都要將新地址寫入R1
六 批量數(shù)據(jù)加載/存儲指令
LDM(或 STM)指令LDM(或STM){條件}{類型} 基址寄存器{!},寄存器列表{ }
LDM(或 STM)指令用于從由基址寄存器所指示的一片連續(xù)存儲器到寄存器列表所指示的多
個寄存器之間傳送數(shù)據(jù),該指令的常見用途是將多個寄存器的內(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ù)據(jù)傳送之外,還將SPSR到CPSR。同時,該后綴還表示傳入或傳出的是用戶模式下的寄存器,而不是當(dāng)前模式下的寄存器。
評論