學習筆記,用於ARM初學者查找命令,精簡於ARM匯編指令集匯總
數據處理指令
數據傳送指令
MOV指令
MOV{條件}{S} 目的寄存器,源操作數
MOV R1,R0 ;將寄存器R0的值傳送到寄存器R1
MOV PC,R14 ;將寄存器R14的值傳送到PC,常用於子程序返回
MOV R1,R0,LSL#3 ;將寄存器R0的值左移3位后傳送到R1(即乘8)
MOVS PC, R14 ;將寄存器R14的值傳送到PC中,返回到調用代碼並恢復標志位
MVN指令
MVN{條件}{S} 目的寄存器,源操作數
MVN R0,#0 ;將立即數0取反傳送到寄存器R0中,完成后R0=-1(有符號位取反)
算數運算指令
ADD指令
ADD{條件}{S} 目的寄存器,操作數1,操作數2
ADD R0,R1,R2 ;R0 = R1 + R2
ADD R0,R1,#256 ;R0 = R1 + 256
ADD R0,R2,R3,LSL#1 ;R0 = R2 + (R3 << 1)
ADC指令
ADC{條件}{S} 目的寄存器,操作數1,操作數2
ADDS R0,R4,R8 ;加低端的字,R0=R4+R8
ADCS R1,R5,R9 ;加第二個字,帶進位,R1=R5+R9+'C'
ADCS R2,R6,R10 ;加第三個字,帶進位,R2=R6+R10+'C'
ADC R3,R7,R11 ;加第四個字,帶進位,R3=R7+R11+'C'
SUB指令
SUB{條件}{S} 目的寄存器,操作數1,操作數2
SUB R0,R1,R2 ;R0 = R1 - R2
SUB R0,R1,#256 ;R0 = R1 - 256
SUB R0,R2,R3,LSL#1 ;R0 = R2 - (R3 << 1)
SBC指令
SBC{條件}{S} 目的寄存器,操作數1,操作數2
SBC RO,R1,R2 ;R0 = R1 - R2 - '!C'
SUBS R0,R1,R2 ;R0 = R1 - R2 - '!C',並根據結果設置CPSR的進位標志位
;注意不要忘記設置S后綴來更改進位標志
比較指令
CMP指令
CMP{條件} 操作數1,操作數2
CMP R1,R0 ;將寄存器R1的值與寄存器R0的值相減,並根據結果設置CPSR的標志位
CMP R1,#100 ;將寄存器R1的值與立即數100相減,並根據結果設置CPSR的標志位
CMN指令
CMN{條件} 操作數1,操作數2
CMN R1,R0 ;將寄存器R1的值與寄存器R0的值相加,並根據結果設置CPSR的標志位
CMN R1,#100 ;將寄存器R1的值與立即數100相加,並根據結果設置CPSR的標志位
邏輯運算指令
AND指令
AND{條件}{S} 目的寄存器,操作數1,操作數2
AND R0,R0,#3 ; 該指令保持R0的0、1位,其余位清零。
ORR指令
ORR{條件}{S} 目的寄存器,操作數1,操作數2
ORR R0,R0,#3 ; 該指令設置R0的0、1位,其余位保持不變。
EOR指令
EOR{條件}{S} 目的寄存器,操作數1,操作數2
EOR R0,R0,#3 ;該指令反轉R0的0、1位,其余位保持不變。
BIC指令
BIC{條件}{S} 目的寄存器,操作數1,操作數2
BIC R0,R0,#%1011 ;該指令清除 R0 中的位 0、1、和 3,其余的位保持不變。
測試指令
TST指令
TST{條件} 操作數1,操作數2
TST R1,#%1 ;用於測試在寄存器R1中是否設置了最低位(%表示二進制數)
TST R1,#0xffe ;將寄存器R1的值與立即數0xffe按位與,並根據結果設置CPSR的標志位
TEQ指令
TEQ{條件} 操作數1,操作數2
TEQ R1,R2 ;將寄存器R1的值與寄存器R2的值按位異或,並根據結果設置CPSR的標志位
乘法指令
MUL指令
MUL{<condition>}{S} <Rd>,<Rm>,<Rs> ;將Rm和Rs中的值相乘,結果的最低32位保存到Rd中
;參數說明
;S:S位(bit[20])決定指令的操作是否影響CPSR中的條件標志位N位和Z位的值。
;當S=1時,跟新CPSR中的條件標志位的值;當S=0,指令不更新CPSR中的條件標志位。
;<Rd>:寄存器位目標寄存器
;<Rm>:第一個乘數所在寄存器
;<Rs>:第二個乘數所在寄存器
MUL R1,R2,R3 ;R1=R2*R3
MLA指令
MLA{<condition>}{S} <Rd>,<Rm>,<Rs>,<Rn> ;將Rm和Rs中的值相乘,再將乘積加上第三個操作數Rn,結果的最低32保存到Rd中
MOV R0,#0x0A
MLA R1,R2,R3,R0 ;R1=R2*R3+10
UMULL指令
UMULL{<condition>}{S} <RdLo>,<RdHi>,<Rm>,<Rs> ;UMULL為64位無符號乘法指令,指令將Rm和Rs中的值做無符號數相乘,結果的低32位保存到RsLo中,而高32位保存到RdHi中
;參數說明
;<RdLo>:寄存器位目標寄存器,存儲結果的低32位值
;<RdHi>:寄存器位目標寄存器,存儲結果的高32位值
UMULL R0,R1,R5,R8 ;((R1,R0)=R5*R8
UMLAL指令
UMLAL{<condition>}{S} <RdLo>,<RdHi>,<Rm>,<Rs> ;UMLAL位64位無符號長乘-累加指令,指令將Rm和Rs中的值做無符號數相乘,64位乘積與RdHi,RdLo相加,結果的低32位保存到RsLo中,而高32位保存到RdHi中
UMLAL R0,R1,R5,R8 ;(R1,R0)=R5*R8+(R1,R0)
SMULL指令
SMULL{<condition>}{S} <RdLo>,<RdHi>,<Rm>,<Rs> ;SMULL64位有符號長乘指令,指令將Rm和Rs中的值做有符號數相乘,結果的低32位保存到RsLo中,而高32位保存到RdHi中
SMULL R2,R3,R7,R6 ;(R3,R2)=R7*R6
SMLAL
SMLAL{<condition>}{S} <RdLo>,<RdHi>,<Rm>,<Rs> ;SMLAL為64位有符號長乘法指令,指令將Rm和Rs中的值做有符號數相乘,64位乘積與RdHi,RdLo相加,結果的低32位保存到RsLo中,而高32位保存到RdHi中
SMLAL R2,R3,R7,R6 ;(R3,R2)=R7*R6+(R3,R2)
轉移指令
B指令
B{條件} 目標地址
B Label ;程序無條件跳轉到標號Label處執行
CMP R1,#0 ;當CPSR寄存器中的Z條件碼置位時,程序跳轉到標號Label處執行
BEQ Label
BL指令
BL{條件} 目標地址
BL Label ;當程序無條件跳轉到標號Label處執行時,同時將當前的PC值保存到R14中
BLX指令
BLX 目標地址
;BLX指令從ARM指令集跳轉到指令中所指定的目標地址,並將處理器的工作狀態有ARM狀態切換到Thumb狀態,該指令同時將PC的當前內容保存到寄存器R14中
BX指令
BX{條件} 目標地址
;BX指令跳轉到指令中所指定的目標地址,目標地址處的指令既可以是ARM指令,也可以是Thumb指令
程序狀態寄存器訪問指令
MRS指令
MRS{條件} 通用寄存器,程序狀態寄存器(CPSR或SPSR)
MRS R0,CPSR ;傳送CPSR的內容到R0
MRS R0,SPSR ;傳送SPSR的內容到R0
MSR指令
MSR{條件} 程序狀態寄存器(CPSR或SPSR)_<域>,操作數
位[31:24]為條件標志位域,用f表示;
位[23:16]為狀態位域,用s表示;
位[15:8]為擴展位域,用x表示;
位[7:0]為控制位域,用c表示;
MSR CPSR,R0 ;傳送R0的內容到CPSR
MSR SPSR,R0 ;傳送R0的內容到SPSR
MSR CPSR_c,R0 ;傳送R0的內容到SPSR,但僅僅修改CPSR中的控制位域
加載/存儲指令
LDR指令
LDR{條件} 目的寄存器,<存儲器地址>
LDR R0,[R1] ;將存儲器地址為R1的字數據讀入寄存器R0。
LDR R0,[R1,R2] ;將存儲器地址為R1+R2的字數據讀入寄存器R0。
LDR R0,[R1,#8] ;將存儲器地址為R1+8的字數據讀入寄存器R0。
LDR R0,[R1,R2] ! ;將存儲器地址為R1+R2的字數據讀入寄存器R0,並將新地址R1+R2寫入R1。
LDR R0,[R1,#8] ! ;將存儲器地址為R1+8的字數據讀入寄存器R0,並將新地址R1+8寫入R1。
LDR R0,[R1],R2 ;將存儲器地址為R1的字數據讀入寄存器R0,並將新地址R1+R2寫入R1。
LDR R0,[R1,R2,LSL#2]! ;將存儲器地址為R1+R2×4的字數據讀入寄存器R0,並將新地址R1+R2×4寫入R1。
LDR R0,[R1],R2,LSL#2 ;將存儲器地址為R1的字數據讀入寄存器R0,並將新地址R1+R2×4寫入R1。
LDRB指令
LDR{條件}B 目的寄存器,<存儲器地址>
LDRB R0,[R1] ;將存儲器地址為R1的字節數據讀入寄存器R0,並將R0的高24位清零。
LDRB R0,[R1,#8] ;將存儲器地址為R1+8的字節數據讀入寄存器R0,並將R0的高24位清零。
LDRH指令
LDR{條件}H 目的寄存器,<存儲器地址>
LDRH R0,[R1] ;將存儲器地址為R1的半字數據讀入寄存器R0,並將R0的高16位清零。
LDRH R0,[R1,#8] ;將存儲器地址為R1+8的半字數據讀入寄存器R0,並將R0的高16位清零。
LDRH R0,[R1,R2] ;將存儲器地址為R1+R2的半字數據讀入寄存器R0,並將R0的高16位清零。
STR指令
STR{條件} 源寄存器,<存儲器地址>
STR R0,[R1],#8 ;將R0中的字數據寫入以R1為地址的存儲器中,並將新地址R1+8寫入R1。
STR R0,[R1,#8] ;將R0中的字數據寫入以R1+8為地址的存儲器中。
STRB指令
STR{條件}B 源寄存器,<存儲器地址>
STRB R0,[R1] ;將寄存器R0中的字節數據寫入以R1為地址的存儲器中。
STRB R0,[R1,#8] ;將寄存器R0中的字節數據寫入以R1+8為地址的存儲器中。
STRH指令
STR{條件}H 源寄存器,<存儲器地址>
STRH R0,[R1] ;將寄存器R0中的半字數據寫入以R1為地址的存儲器中。
STRH R0,[R1,#8] ;將寄存器R0中的半字數據寫入以R1+8為地址的存儲器中。
LDM/STM指令
LDM(或STM){條件}{類型} 基址寄存器{!},寄存器列表{∧}
;參數說明
;類型
IA 每次傳送后地址加1;
IB 每次傳送前地址加1;
DA 每次傳送后地址減1;
DB 每次傳送前地址減1;
FD 滿遞減堆棧;
ED 空遞減堆棧;
FA 滿遞增堆棧;
EA 空遞增堆棧;
{!} 為可選后綴,若選用該后綴,則當數據傳送完畢之后,將最后的地址寫入基址寄存器,否則基址寄存器的內容不改變
基址寄存器不允許為R15,寄存器列表可以為R0~R15的任意組合
{∧} 為可選后綴,當指令為LDM且寄存器列表中包含R15,選用該后綴時表示:除了正常的數據傳送之外,還將SPSR復制到CPSR
STMFD R13!,{R0,R4-R12,LR} ;將寄存器列表中的寄存器(R0,R4到R12,LR)存入堆棧
LDMFD R13!,{R0,R4-R12,PC} ;將堆棧內容恢復到寄存器(R0,R4到R12,LR)
異常產生指令
SWI指令
SWI{條件} 24位的立即數 ;SWI指令用於產生軟件中斷,以便用戶程序能調用操作系統的系統例程
SWI 0x02 ;該指令調用操作系統編號位02的系統例程。
BKPT指令
BKPT 16位的立即數 ;BKPT指令產生軟件斷點中斷,可用於程序的調試。
偽指令
AREA指令
語法格式:AREA 段名 屬性 1 ,屬性 2 ,.... ;AREA 偽指令用於定義一個代碼段或數據段
;常用屬性如下
— CODE 屬性:用於定義代碼段,默認為 READONLY 。
— DATA 屬性:用於定義數據段,默認為 READWRITE 。
— READONLY 屬性:指定本段為只讀,代碼段默認為 READONLY 。
— READWRITE 屬性:指定本段為可讀可寫,數據段的默認屬性為 READWRITE 。
— ALIGN 屬性:使用方式為ALIGN 表達式。在默認時,ELF(可執行連接文件)的代碼段和數據段是按字對齊的,表達式的取值范圍為 0 ~31,相應的對齊方式為2表達式次方。
— COMMON 屬性:該屬性定義一個通用的段,不包含任何的用戶代碼和數據。各源文件中同名的 COMMON 段共享同一段存儲單元。
AREA Init , CODE , READONLY ;該偽指令定義了一個代碼段,段名為 Init ,屬性為只讀。
ALIGN指令
ALIGN { 表達式 { ,偏移量 }} ;ALIGN 偽指令可通過添加填充字節的方式,使當前位置滿足一定的對其方式
AREA Init,CODE ,READONLY,ALIEN=3;指定后面的指令為 8 字節對齊。
....
;指令序列
....
END
CODE16/CODE32指令
CODE16 偽指令通知編譯器,其后的指令序列為 16 位的 Thumb 指令。
CODE32 偽指令通知編譯器,其后的指令序列為 32 位的 ARM 指令
AREA Init ,CODE ,READONLY
....
CODE32 ;通知編譯器其后的指令為 32 位的 ARM 指令
LDR R0,=NEXT+1 ;將跳轉地址放入寄存器 R0
BX R0 ;程序跳轉到新的位置執行,並將處理器切換到 Thumb 工作狀態
....
CODE16 ;通知編譯器其后的指令為 16 位的 Thumb 指令
NEXT LDR R3,=0x3FF
....
END ;程序結束
ENTRY指令
ENTRY ;用於指定匯編程序的入口點
AREA Init , CODE , READONLY
ENTRY ;指定應用程序的入口點
.....
END 指令
END ;用於通知編譯器已經到了源程序的結尾
AREA Init , CODE , READONLY
......
END ;指定應用程序的結尾