ARM 指令集摘要
簡介: ARM指令系統一般有Thumb指令集和ARM指令集。
Thumb: 指令集具有靈活、小巧的特點,是16位的
ARM:指令集支持ARM核所有的特性,具有高效、快速的特點,是32位的
一 尋址方式
a) 寄存器尋址(操作數的值在寄存器中)
mov r1, r2 // r1 = r2
b) 立即尋址(操作數在指令中)
mov r1, #0xff00 //r1 = 0xff00
c) 寄存器移位尋址(第2個操作數是寄存器移位方式)
mov r1, r2, lsl #3 //r1 = r2 << 3
d) 寄存器簡介尋址(第2個寄存器中給出的是操作數的地址)
ldr r0, [r2] //r0 = [r2]
e) 基址尋址(將基址寄存器的值和指令中的偏移相加得到操作數的地址)
ldr r0, [r1, #0x0c] //r0 = [r1 + 0x0c]
f) 多寄存器尋址(一次可以最多傳送16個寄存器的值)
ldmia r1!, {r2-r4, r6} // r2 = [r1], r1 = r1 + 4, r3 = [r1], ……
g) 堆棧尋址(先進後出)
滿遞增:堆棧向上增長,堆棧指針指向內含有效數據項的最高地址。指令如LDMFA、STMFA等;
空遞增:堆棧向上增長,堆棧指針指向堆棧上的第一個空位置。指令如LDMEA、STMEA等
滿遞減:堆棧向下增長,堆棧指針指向內含有效數據項的最低地址。指令如LDMFD、STMFD等
空遞減:堆棧向下增長,堆棧指針向堆棧下的第一個空位置。指令如LDMED、STMED等
h) 塊拷貝尋址
STMIA R0!,{R1-R7} ;將R1~R7的數據保存到存儲器中。
;存儲指針在保存第一個值之後增加,;增長方向爲向上增長
STMIB R0!,{R1-R7} ;將R1~R7的數據保存到存儲器中。
;存儲指針在保存第一個值之前增加,;增長方向爲向上增長。
i) 相對尋址: 相對尋址是基址尋址的一種變通。由程序計數器PC提供基準地址,指令中的地址碼字段作爲偏移量,兩者相加後得到的地址即爲操作數的有效地址。
bl / beq
二 CPSR(程序狀態寄存器)格式
31 30 29 28 27 …… 8 7 6 5 4 3 2 1 0
+--+--+--+--+----------------- +--+--+--+----+-----+----+-----+-----+-
| N | Z | C | V| - | - | ……. -| - | I | F | T | M4| M3 | M2 | M1 | M0 |
+--+--+--+--+-----------------+--+--+--+----+-----+----+-----+-----+-
N: 當用兩個補碼錶示的帶符號數進行運算時N=1表示運算結果爲負數; N=0表示結果爲正或0
Z: Z = 1 表示運算結果爲0, Z = 0 表示運算結果爲非0
C: 有4中方法設置C, 1) 加法運算: 當結果產生進位時C=1,否則C=0; 2) 減法運算: 當運算產生借位時C=0,否則C=1; 3)對於移位操作, C爲移出值的最後一位; 4) 對於其他指令, C的值通常不變.
V: 對於加減運算, 當操作數和結果爲2進制補碼錶示的帶符號數時,V=1表示符號爲溢出.
I: I=1 禁止IRQ中斷
F: F=1 禁止FIQ中斷
T T=1 運行於Thumb狀態, 否則運行於ARM狀態
M[4:0]: 1) 0b10000 用戶模式 PC, CPSR, R0-R14 2)
2) 0b10001 FIQ模式 PC, CPSR, SPSR_fiq, R0- R7, R8_fiq – R14_fiq
3) 0b10010 IRQ模式 PC, CPSR, SPSR_irq, R0- R12, R13_irq – R14_irq
4) 0b10011 管理模式 PC, CPSR, SPSR_svc R0- R12, R13_svc – R14_svc
5) 0b10111 終止模式 PC, CPSR, SPSR_abt, R0- R12, R13_abt – R14_abt
6) 0b11011 未定義模式 PC, CPSR, SPSR_und, R0- R12, R13_und – R14_und
7) 0b11111 系統模式 PC, CPSR, R0- R14
三 指令集
1 格式: <opcode>{<cond>}{s} <rd>, <rn>{<operand2>}
opcode:指令助記符; cond:執行條件; S:是否影響CPSR寄存器的值;
Rd:目標寄存器; Rn:第1個操作數的寄存器; operand2:第2個操作數;
靈活的使用第2個操作數“operand2”能夠提高代碼效率。它有如下的形式:
§ #immed_8r——常數表達式;
§ Rm——寄存器方式;
§ Rm,shift——寄存器移位方式;
常數格式必須爲8位常數循環右移偶數位的值.
移位方法有:
操作碼 |
說明 |
操作碼 |
說明 | |
ASR #n |
算術右移n位 |
ROR #n |
循環右移n位 | |
LSL #n |
邏輯左移n位 |
RRX |
帶擴展的循環右移1位 | |
LSR #n |
邏輯右移n位 |
Type Rs |
Type爲移位的一種類型,Rs爲偏移量寄存器,低8位有效。 | |
所有的ARM指令都可以條件執行,而Thumb指令只有B(跳轉)指令具有條件執行功能。如果指令不標明條件代碼,將默認爲無條件(AL)執行
操作碼 |
條件助記符 |
標誌 |
含義 |
0000 |
EQ |
Z=1 |
相等 |
0001 |
NE |
Z=0 |
不相等 |
0010 |
CS/HS |
C=1 |
無符號數大於或等於 |
0011 |
CC/LO |
C=0 |
無符號數小於 |
0100 |
MI |
N=1 |
負數 |
0101 |
PL |
N=0 |
正數或零 |
0110 |
VS |
V=1 |
溢出 |
0111 |
VC |
V=0 |
沒有溢出 |
1000 |
HI |
C=1,Z=0 |
無符號數大於 |
1001 |
LS |
C=0,Z=1 |
無符號數小於或等於 |
1010 |
GE |
N=V |
有符號數大於或等於 |
1011 |
LT |
N!=V |
有符號數小於 |
1100 |
GT |
Z=0,N=V |
有符號數大於 |
1101 |
LE |
Z=1,N!=V |
有符號數小於或等於 |
1110 |
|
任何 |
無條件執行 (指令默認條件) |
1111 |
NV |
任何 |
從不執行(不要使用) |
2 指令集:
a)存儲器訪問指令
1 單寄存器存取
LDR/STR指令用於對內存變量的訪問、內存緩衝區數據的訪問、查表、外圍部件的控制操作等。若使用LDR指令加載數據到PC寄存器,則實現程序跳轉功能,這樣也就實現了程序散轉。
助記符 |
說明 |
操作 |
條件碼位置 |
|
加載字數據 |
Rd←[addressing],addressing索引 |
LDR{cond} |
|
加載無符號字節數據 |
Rd←[addressing],addressing索引 |
LDR{cond}B |
|
以用戶模式加載字數據 |
Rd←[addressing],addressing索引 |
LDR{cond}T |
|
以用戶模式加載無符號字節數據 |
Rd←[addressing],addressing索引 |
LDR{cond}BT |
|
加載無符號半字數據 |
Rd←[addressing],addressing索引 |
LDR{cond}H |
|
加載有符號字節數據 |
Rd←[addressing],addressing索引 |
LDR{cond}SB |
|
加載有符號半字數據 |
Rd←[addressing],addressing索引 |
LDR{cond}SH |
助記符 |
說明 |
操作 |
條件碼位置 |
|
存儲字數據 |
[addressing]←Rd, addressing索引 |
STR{cond} |
|
存儲字節數據 |
[addressing]←Rd, addressing索引 |
STR{cond}B |
|
以用戶模式存儲字數據 |
[addressing]←Rd, addressing索引 |
STR{cond}T |
|
以用戶模式存儲字節數據 |
[addressing]←Rd, addressing索引 |
STR{cond}BT |
|
存儲半字數據 |
[addressing] ←Rd, addressing索引 |
STR{cond}H |
LDR R2,[R5] ;將R5指向地址的字數據存入R2
ldr rd, [rd1], #0x04 // rd = [rd1], rd1 = rd1 + 0x04
STR R1,[R0,#0x04] ;將R1的數據存儲到R0+0x04地址
str rd, [rd1], #4 // [rd1] = rd, rd1 = rd1 + 4
LDRB R3,[R2],#1 ;將R2指向地址的字節數據存入R3,R2=R2+1
STRB R6,[R7] ;將R7指向地址的字節數據存入R6
LDRSB R1,[R0,R3] ;將R0+R3地址上的字節數據存入R1,高24位用符號擴展
LDRH R6,[R2],#2 ; ;將R2指向地址的半字數據存入R6,高16位用0擴展讀出後,R2=R2+2
STRH R1,[R0,#2]! ;將R1的半字數據保存到R0+2地址,只修改低2字節數據,R0=R0+2
str r1, [r0, #2]! ;( [r0 + 2] = r1, r0 = r0 + 2)
2. 多寄存器操作
多寄存器加載/存儲指令可以實現在一組寄存器和一塊連續的內存單元之間傳輸數據。LDM爲加載多個寄存器;STM爲存儲多個寄存器。允許一條指令傳送16個寄存器的任何子集或所有寄存器。它們主要用於現場保護、數據複製、常數傳遞等
LDM{cond}<mode> Rn{!}, reglist{^} //多寄存器加載 reglist ß [Rn…],
STM{cond}<mode> Rn{!}, reglist{^} //多寄存器存儲 [Rn…] ß reglist
cond爲條件碼, mode爲控制地址的增長方式, !表示在操作結束後,將結果寫回Rn, ^爲當進行數據傳送且寄存器列表不含pc時,加載/存儲的寄存器是用戶模式下的, 若在LDM下使用PC,則除正常的寄存器操作外,還將SPSR拷貝到CPSR中(它不能用在用戶和系統模式下), reglist :表示寄存器列表,可以包含多個寄存器,它們使用“,”隔開,如{R1,R2,R6-R9},寄存器由小到大排列;
mode:
模式 |
說明 |
模式 |
說明 |
IA |
每次傳送後地址加4 |
FD |
滿遞減堆棧 |
IB |
每次傳送前地址加4 |
ED |
空遞減堆棧 |
DA |
每次傳送後地址減4 |
FA |
滿遞增堆棧 |
DB |
每次傳送前地址減4 |
EA |
空遞增堆棧 |
數據塊傳送操作 |
堆棧操作 |
進行數據複製時,先設置好源數據指針和目標指針,然後使用塊拷貝尋址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB進行讀取和存儲 。
進行堆棧操作操作時,要先設置堆棧指針(SP),然後使用堆棧尋址指令STMFD/LDMFD 、STMED/LDMED、STMFA/LDMFA和STMEA/LDMEA實現堆棧操作。
STMDA r0!, {r5-r6} … LDMIB r0!, {r5-r6}
STMED r0!, {r5, r6} …. LDMED r0!, {r5-r6}
b) 寄存器和存儲器交換指令
SWP{cond}{B} Rd, Rm, [Rn] Rd ß[Rn] , [Rn] ß Rm
swp r1, r1, [r0] 將R1的內容與R0指向的存儲單元的內容進行交換
swpb r1, r2, [r0] 將R0指向的存儲單元的內容讀取一個字節存入R1,並將R2的內容寫入該內存單元
c) 數據處理指令
1 數據傳送
MOV{cond}{S} Rd, operand2 Rd ß operand2 如 mov r1, #0x10 / movs r3, r1, lsl, #2
MVN{cond}{s} Rd, operand2 Rd ß (~operand2) 如 mvn r1, #0xff ; r1=0xffffff00
2 算術指令
ADD{cond}{S} Rd, Rn, operand2 ;Rd ßRn+operand2 如 add r1, r1, r2 ; r1 = r1 + r2
SUB{cond}{S} Rd, Rn, operand2 ;Rd ß Rn – operand2 如 subs r0, r0, #1 ; r0 = r0 – 1
RSB{cond}{S} Rd, Rn, operand2 ;Rd ßoperand2 –Rn 如 rsb r3, r1, #0xff00 ; r3 = 0xff00 – r1
ADC{cond}{S} Rd, Rn, operand2 ;Rd ß Rn + operand2 + Carry 如 adc r1, r1, r3 ; r1 = r1 + r3 +進位標誌
SBC{cond}{S} Rd, Rn, operand2 ;Rd ßRn – operand2 – (Not)Carry 如 sbc r1, r1, r3; r1=r1–r3–借位標誌
RSC{cond}{S} Rd, Rn, operand2 ;Rd ßoperand2 – Rn – (Not)Carry 如 rsc r3, r1, #0
3 邏輯運算指令
AND{cond}{s} Rd, Rn, operand2 Rd ßRn & operand2 如 and r2, r1, r3 ; r2 = r1 & r3
ORR{cond}{s} Rd, Rn, operand2 Rd ß Rn |operand2 如 orr r0, r0, #0x0f ; r0 = r0 | 0x0f
EOR{cond}{s} Rd, Rn, operand2 Rd ß Rn ^ operand2 如 eor r1, r1, #0x0f ; r1 = r1 ^ 0x0f
BIC{cond}{s} Rd, Rn, operand2 Rd ß Rn &( ~operand2) 如 bic r1, r1, #0x0f ;將R1的低4位清0
4 比較指令
CMP{cond} Rn, operand2 標誌N,Z,C,V ß Rn – operand2 如 cmp r1, #10 ;R1與10比較,設置相關標誌位
CMN{cond} Rn, operand2 標誌N,Z,C,V ß Rn + operand2 如 cmn r1, #1 ;R0+1,判斷R0是否爲1的補碼
如果是,則設置Z標誌位
TST{cond} Rn, operand2 標誌N,Z,C,V ß Rn & operand2 如 tst r1, #0x01 ;判斷R0的最低位是否爲0
TEQ{cond} Rn, operand2 標誌N,Z,C,V ß Rn ^ operand2 如 teq r0, r1 ;比較R0與R1是否相等 (不影響V位和C位)
5 乘法指令
1 32位乘法
MUL{cond}{s} Rd, Rm, Rs Rd ßRm * Rs (Rd != Rm) Mul r1, r2, r3 ; r1 = r2 * r3
MLA{cond}{s} Rd, Rm, Rs,Rn Rd ßRm * Rs + Rn (Rd != Rm) Mla r1, r2, r3, r0 ; r1 = r2 * r3 + r0
2 64位
UMULL{cond}{s} RdLo, RdHi, Rm,Rs (RdLo.RdHi) ß Rm * Rs Umull r0, r1, r5, r8 ;(r1,r0) = r5 * r8
UMLAL{cond}{s} RdLo, RdHi, Rm,Rs (RdLo.RdHi) ß Rm * Rs +(RdLo.RdHi)
umlal r0, r1, r5, r8 ;(r1,r0) = r5 * r8 + (r1, r0)
SMULL{cond}{s} RdLo, RdHi, Rm,Rs (RdLo.RdHi) ß Rm * Rs Smull r2,r3, r7, r6 ;(r3,r2) = r7 * r6
SMLAL{cond}{s} RdLo, RdHi, Rm,Rs (RdLo.RdHi) ß Rm * Rs +(RdLo.RdHi)
smlal r2, r3, r7, r6 ;(r3,r2) = r7 * r6 + (r3, r2)
d) 分支指令
B{cond} Label PCß label B WAITA ;跳轉到WAITA標號處
BL{cond} Label LRßPC – 4, PC ß label ;BL delay ;調用子程序delay,delay結束會後將lr存入PC,即返回
BX{cond} Rm PCßRm, 切換處理器狀態(通過Rm[0]指示) BX R0;跳轉到R0,並根據R0的最低位來切換處理器狀態
e) 協處理器指令
CDP{cond} coproc, opcode1, CRd, CRn, CRm{, opcode2} //通知協處理器執行特定的操作
CDP p7,0,c0,c2,c3,0 ;對協處理器7操作,操作碼爲0,可選操作碼爲0
LDC{cond}{L} coproc, CRd, <地址> 數據讀取指令
LDC p5,c2,[R2,#4] ;讀取R2+4指向的內存單元的數據,傳送到協處理器p5的c2寄存器中
STC{cond}{L} coproc, CRd, <地址> 數據存儲指令
STC p5,c1,[R0] ;將協處理器p5的C1寄存器內數據傳送到R0指向的內存單元
MCR{cond} coproc,opcode1, Rd, CRn, CRm{,opcode2} //寄存器間數據交換(ARM à 協處理器)
MCR p6,2,R7,c1,c2 ;將ARM中的R7寄存器內容傳遞到協處理器6的C1和C2寄存器
MRC{cond} coproc,opcode1, Rd, CRn, CRm{,opcode2} //寄存器間數據交換(協處理器à ARM)
MRC p5,2,R2,c3,c2 ;將協處理器5的C3和C2寄存器內容傳遞到ARM中的R2寄存器
f) 雜項指令
SWI{cond} immed_24 產生軟中斷,處理器進入管理模式,並且將CPSR保存到管理模式的SPSR中
SWI 12 ;調用12號軟中斷
MRS{cond} Rd, psr Rd ß psr psr爲CPSR,SPSR
MRS R1,CPSR ; 將CPSR狀態寄存器讀取,保存到R1中
MSR{cond} psr_fields, Rd / immed_8r psr_fields ßRd / immed_8r,
fields:c(psr[7..0]), x(psr[15..8]), s(psr[23…16]), f(psr[31…24])的一個組合
g) 僞指令
ADR{cond} register, expr //將基於PC相對偏移的地址值或基於寄存器相對偏移的地址值讀取到寄存器中
ADR R0, delay ; 將標號delay的地址存入R0
……
Delay
Mov r0, r14
ADRL{cond} register, expr //將基於PC相對偏移的地址值或基於寄存器相對偏移的地址值讀取到寄存器中,比ADR可以讀取更大範圍的地址, 用法同ADR
LDR{cond} register, =expr //用於加載32位的立即數或一個地址值到指定寄存器
LDR R0, =delay ; 將標號delay的地址存入R0
……
Delay:
Mov r0, r14
與LDR指令相比, 此僞指令的操作數有 “ = ”
NOP 空操作