很好的 ARM指令集解析
ARM指令和指令系統(tǒng):
指令是指示計算機某種操作的命令,指令的集合稱為指令系統(tǒng)。指令系統(tǒng)的功能強弱很大程度上決定了這類計算機智能的高低,它集中地反應了微處理器的硬件功能和屬性。
ARM指令在機器中的表示格式是用32位的二進制數(shù)表示。如ARM中有一條指令為
ADDEQS R0,R1,#8;
其二進制代碼形式為:
31~28 | 27~25 |
ARM指令和指令系統(tǒng):
指令是指示計算機某種操作的命令,指令的集合稱為指令系統(tǒng)。指令系統(tǒng)的功能強弱很大程度上決定了這類計算機智能的高低,它集中地反應了微處理器的硬件功能和屬性。
ARM指令在機器中的表示格式是用32位的二進制數(shù)表示。如ARM中有一條指令為
ADDEQS R0,R1,#8;
其二進制代碼形式為:
31~28 | 27~25 | 24~21 | 20 | 19~16 | 15~12 | 11~0
0000 | 001 | 0100 | 1 | 0001 | 0000 | 0000 0000 1000
cond | opcode | Rn | Rd | Op2
ARM指令格式一般如下:
{}{s},{,}
格式中< >的內(nèi)容是必不可少的,{ }中的內(nèi)容可忽略
表示操作碼。如ADD表示算術加法
{} 表示指令執(zhí)行的條件域。如EQ、NE等,缺省為AL。
{S} 決定指令的執(zhí)行結(jié)果是否影響CPSR的值,使用該后綴則指令執(zhí)行結(jié)果影響CPSR的值,否則不影響
表示目的寄存器
表示第一個操作數(shù),為寄存器
表示第二個操作數(shù),可以是立即數(shù)。寄存器和寄存器移位操作數(shù)
ARM指令后綴:S、!
S后綴:指令中使用S后綴時,指令執(zhí)行后程序狀態(tài)寄存器的條件標志位將被刷新,不使用S后綴時,指令執(zhí)行后程序狀態(tài)寄存器的條件標志將不會發(fā)生變化。S后綴常用于對條件進行測試,如是否有溢出,是否進位等,根據(jù)這些變化,就可以進行一些判斷,如是否大于,相等,從而影響指令執(zhí)行的順序。
!后綴:如果指令地址表達式中不含!后綴,則基址寄存器中的地址值不會發(fā)生變化。加上此后綴后,基址寄存器中的值(指令執(zhí)行后) = 指令執(zhí)行前的值 + 地址偏移量
(1)!后綴必須緊跟在地址表達式后面,而地址表達式要有明確的地址偏移量
(2)!后綴不能用于R15(PC)的后面
(3)當用在單個地址寄存器后面時,必須確信這個寄存器有隱性的偏移量,例如“STMDB R1!,{R3,R5,R7}”。此時地址基址寄存器R1的隱性偏移量為4(一條指令占32位,即4個字節(jié))
指令的條件碼:31-28位4個字節(jié)存儲,共16個條件碼
條件碼 助記符后綴 標志 含義
0000 EQ Z置位 相等
0001 NE Z清零 不相等
0010 CS C置位 無符號數(shù)大于或等于
0011 CC C清零 無符號數(shù)小于
0100 MI N置位 負數(shù)
0101 PL N清零 正數(shù)或零
0110 VS V置位 溢出
0111 VC V清零 未溢出
1000 HI C置位 Z清零 無符號數(shù)大于
1001 LS C清零 Z置位 無符號數(shù)小于或等于
1010 GE N等于V 帶符號數(shù)大于或等于
1011 LT N不等于V 帶符號數(shù)小于
1100 GT Z清零且(N等于V) 帶符號數(shù)大于
1101 LE Z置位或(N不等于V) 帶符號數(shù)小于或等于
1110 AL 忽略 無條件執(zhí)行
ARM指令分類:六大類
ARM指令集可以分為數(shù)據(jù)處理指令,數(shù)據(jù)加載指令和存儲指令,分支指令,程序狀態(tài)寄存器(PSR)處理指令,協(xié)處理器指令和異常產(chǎn)生指令六大類。
ARM指令的尋址方式:8類
ARM指令的尋址方式一般可以分為8類:立即數(shù)尋址,寄存器尋址,寄存器間接尋址,寄存器移位尋址,基址變址尋址,多寄存器尋址,相對尋址,堆棧尋址等
舉例:
MOV R0,#15 ;立即數(shù)15放入寄存器R0中
ADD R0,R1,R2 ;R0 <= R1+R2
LDR R0,[R4] ;R0 <= [R4](R4中存放的是一個指針變量,[ ]表示取改地址值指向的內(nèi)容)
ADD R0,R1,R2,LSL #1 ;R0 <= R1+R2(R2左移一位后的值)
MOV R0,R1,LSL R3 ;R0 <= R1(R1左移R3位后)
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]
LDMIA R0!,{R1 - R4} ;R1 <= [R0]、R1 <= [R0+4]、R1 <= [R0+8]、R1 <= [R0+12]
BL proc ;跳轉(zhuǎn)到子程序proc處執(zhí)行,執(zhí)行完畢后返回(L標記,帶返回的跳轉(zhuǎn))。
STMFD R13!,{R0 - R4} ;R0-R4壓棧,F(xiàn)D為滿棧遞減,地址從高到低,R13為SP堆棧指針
LDMFD R13!,{R0 - R4} ;R0-R4出棧,F(xiàn)D為滿棧遞減
ARM寄存器數(shù)據(jù)處理指令:
1、數(shù)據(jù)處理指令機器編碼格式:
31~28 | 27~26 25 | 24~21 | 20 | 19~16 | 15~12 | 11~0
cond | 00 I | opcode | S | Rn | Rd | Op2
cond:指令執(zhí)行的條件碼
I:用于區(qū)別第二操作數(shù)是立即數(shù)(I=1)還是寄存器移位(I=0)
opcode:數(shù)據(jù)處理指令操作碼
S:用于設置條件碼,S=0時,條件碼不改變,S=1時,條件碼根據(jù)具體指令的結(jié)果修改
Rn:第一操作數(shù)寄存器
Rd:目標寄存器
Op2:第二操作數(shù),該數(shù)可以是立即數(shù)或寄存器移位數(shù)
2、數(shù)據(jù)傳送指令:MOV MVN
MOV R1,R0 ;將寄存器R0的值傳送到寄存器R1
MOV PC,R14 ;將寄存器R14的值傳送到PC,常用于子程序返回
MOV R1,R0,LSL #3 ;將寄存器R0的值左移3位后傳送到R1
MOV R0,#5 ;將立即數(shù)5傳送到寄存器R0
MVN R0,#0 ;將立即數(shù)0按位取反后傳送到寄存器R0中,完成后R0 = -1
MVN R1,R2 ;將R2按位取反后,結(jié)果存到R1
3、移位指令:LSL、LSR、ASR、ROR、RRX
MOV R0,R1,LSL #1 ;寄存器R1左移一位后傳送到R0
MOVS R0,R1,LSL #1 ;寄存器R1左移一位后傳送到R0,并更新狀態(tài)標志位
MOVS R0,R1,LSR #1 ;寄存器R1右移一位后傳送到R0,并更新狀態(tài)標志位
MOVS R0,R1,ASR #1 ;寄存器R1算術右移一位后傳送到R0,并更新狀態(tài)標志位
;算術右移,第一位符號位不變
MOV R0,R1,ROR #1 ;寄存器R1循環(huán)右移一位后傳送到R0
MOVS R0,R1,RRX ;寄存器R1循環(huán)右移一位后傳送到R0,用C標志位作為最高位擴展
4、算術指令:ADD、ADC、SUB、SBC、RSB、RSC
ADD R0,R1,R2 ;寄存器R1和R2的值相加后傳送到R0
ADD R0,R1,#5 ;寄存器R1的值加上5后傳送到R0
ADD R0,R1,R2,LSL #2 ;寄存器R2左移兩位后與R1相加,得到的結(jié)果傳送到R0
ADD R0,R1,R2,LSL R3 ;寄存器R2左移R3后與R1相加,得到的結(jié)果傳送到R0
ADDS R0,R2,R4 ;64位加,低位放在R0
ADC R1,R3,R5 ;64位加,高位放在R1,注意要加上低位的進位
SUB R0,R1,R2 ;寄存器R1和R2的值相減后傳送到R0
SUB R0,R1,#6 ;寄存器R1的值減6后傳送到R0
SUB R0,R1,R2,LSL #1 ;R1與寄存器R2左移一位后的值相減,得到的結(jié)果傳送到R0
SUBS R0,R2,R4 ;64位減,低位放在R0
SBC R1,R3,R5 ;64位減,高位放在R1,注意要減去低位的借位
RSB R0,R1,R2 ;寄存器R2和R1的值相減后傳送到R0,注意是R2-R1,方向相反
RSB R0,R1,#6 ;6與寄存器R1的值相減后傳送到R0
RSB R0,R1,R2,LSL #1 ;寄存器R2左移一位后與R1相減,得到的結(jié)果傳送到R0
RSC R0,R1,R2 ;寄存器R2和R1的值相減,再減去借位后傳送到R0
5、邏輯運算指令:AND、ORR、EOR、BIC
AND R0,R0,#0xF ;R0的值與0xF相位與后的值傳送到R0
ORR R0,R0,#9 ;R0的值與9相位與后的值傳送到R0
EOR R0,R0,#0xF ;R0的值與0xF相異或后的值傳送到R0
BIC R0,R0,#9 ;位清除指令R0的第0位和第3位清零
6、比較指令:CMP、CMN、TST、TEQ
CMP R1,#10 ;將寄存器R1的值與10相減,并設置CPSR標志位
ADDGT R0,R0,#5 ;如果R1>10,則執(zhí)行ADDGT指令,將R0加5
CMN R0,R1 ;R0 - (-R1),反值比較,影響CPSR標志位
CMN R0,#10 ;R0 - (-10),反值比較,影響CPSR標志位
TST R1,#3 ;檢查R1中第0位和第1位是否為1,根據(jù)結(jié)果更新條件標志位
TEQ R1,R2 ;將寄存器R1的值與寄存器R2的值進行按位異或,
;并根據(jù)結(jié)果設置CPSR的標志位
7、乘法指令:MUL、MLA、SMULL、SMLAL、UMULL、UMLAL
MUL R0,R1,R2 ;R1和R2相乘的結(jié)果發(fā)送到R0
MULS R0,R1,R2 ;R1和R2相乘的結(jié)果發(fā)送到R0,同時設置CPSR的相關條件標志位
MLA R0,R1,R2,R3 ;R1和R2相乘的結(jié)果再加上R3后發(fā)送到R0
MLAS R0,R1,R2,R3 ;R1和R2相乘的結(jié)果再加上R3后發(fā)送到R0,更新CPSR標志位
SMULL R0,R1,R2,R3 ;R2和R3相乘的結(jié)果的低32位放在R0,高32位放在R1
SMLAL R0,R1,R2,R3 ;R2和R3相乘的結(jié)果的低32位加上R0后放在R0,
;高32位加上R1后放在R1
UMULL R0,R1,R2,R3 ;無符號數(shù)相乘,結(jié)果與SMULL類似
UMLAL R0,R1,R2,R3 ;無符號數(shù)乘加,結(jié)果與SMLAL類似
ARM數(shù)據(jù)加載和存儲指令:
1、數(shù)據(jù)加載和存儲的方向。寄存器到存儲器方向:Store;從存儲器到寄存器方向:Load
數(shù)據(jù)加載和存儲指令共有三種類型:單寄存器加載和存儲指令,多寄存器加載和存儲指令 和 交換指令
2、數(shù)據(jù)加載與存儲器指令尋址
LDR R5,[R6,#0x08] ;R6寄存器加0x08的和的地址值內(nèi)的數(shù)據(jù)傳送到R5
STR R6,[R7],#-0x08 ;R6寄存器的數(shù)據(jù)傳送到R7存儲的地址值指向的存儲空間,
;同時更新R7寄存器的內(nèi)容為R7-0x08
LDR R5,[R6,R3] ;R6寄存器加R3的和的地址值內(nèi)的數(shù)據(jù)傳送到R5
STR R6,[R7],-R8 ;R6寄存器的數(shù)據(jù)傳送到R7存儲的地址值指向的存儲空間,
;同時更新R7寄存器的內(nèi)容為R7-R8
LDR R3,[R2,R4,LSL #2] ;R3 <== [ R2 + R4(R4左移兩位) ]
LDR R3,[R2],-R4,LSR #3 ;R3 <== [ R2 ],R2 = R2-R4(R4右移三位)
LDR R4,START ;將標號START標定的空間的數(shù)據(jù)加載到R4中
3、地址索引:前索引、自動索引、后索引
1】前索引:前索引也稱為前變址,這種索引是在指令執(zhí)行前把偏移量和基址相加減,得到的值作為變量的地址。如:
LDR R5,[R6,#0x04]
STR R0,[R5,-R8]
2】自動索引:自動索引也稱為自動變址,有時為了修改基址寄存器的內(nèi)容,使之指向數(shù)據(jù)傳送地址,可使用這種方法自動修改基址寄存器,如:
LDR R5,[R6,#0x04]!
3】后索引:后索引也被稱為后變址,后索引就是用基址寄存器的地址值尋址,找出操作數(shù)進行操作,操作完成后,再把地址偏移量和基址相加/減,結(jié)果送到基址寄存器,作為下一次尋址的基址。如:
LDR R5,[R6],#0x04
STR R6,[R7],#-0x08
4、單寄存器加載和存儲指令:LDR/STR、LDRB/STRB、LDRH/STRH、LDRSB/LDRSH
1】字數(shù)據(jù)加載/存儲指令格式:
31~28 | 27~26 | 25 24 23 22 21 20| 19~16 | 15~12 | 11~0
cond | 01 | I P U B W L | Rn | Rd | Op2
cond:指令執(zhí)行的條件編碼
I、P、U、W:用于區(qū)別不同的地址模式(偏移量)。
I為0時,偏移量為12位立即數(shù);I為1時,偏移量為移位寄存器移位
P表示前/后索引
U表示加/減
W表示回寫
L:L為1時表示加載,L為0時表示存儲
B:B為1表示字節(jié)訪問,B為0表示字訪問
Rd:源/目標寄存器
Rn:基址寄存器
Op2:表示偏移量是一個12位的無符號二進制數(shù),與Rn一起構成地址addr
2】存儲器<==>寄存器 LDR/STR
LDR指令用于從存儲器中間一個32位的字數(shù)據(jù)加載到目的寄存器Rd中。該指令通常用于從存儲器中讀取32位的字數(shù)據(jù)到通用寄存器,然后對數(shù)據(jù)進行處理。當程序計數(shù)器PC作為目的寄存器時,指令從存儲器中讀取的字數(shù)據(jù)被當做目的地址,從而實現(xiàn)程序流程的跳轉(zhuǎn)。
LDR R4,START ;將存儲地址為START的字數(shù)據(jù)讀入R4
STR R5,DATA1 ;將R5存入存儲地址為DATA1中
LDR R0,[R1] ;將存儲器地址為R1的字數(shù)據(jù)讀入寄存器R0
LDR R0,[R1,R2] ;將存儲器地址為R1+R2的字數(shù)據(jù)讀入寄存器R0
LDR R0,[R1,#8] ;將寄存器R1+8的內(nèi)容讀入寄存器R0
LDR R0,[R1,R2,LSL #2] ;將R1+R2*4的字數(shù)據(jù)讀入寄存器R0
STR R0,[R1,R2]! ;將R0字數(shù)據(jù)存入存儲器地址為R1+R2的存儲單元中,
并將新地址R1+R2寫入R1
STR R0,[R1,#8]! ;將R0字數(shù)據(jù)存入存儲器地址為R1+8的存儲單元中,
并將新地址R1+8寫入R1
STR R0,[R1,R2,LSL #2]! ;將R0字數(shù)據(jù)存入地址為R1+R2*4的存儲單元中,
并將新地址R1+R2*4寫入R1
LDR R0,[R1],#8 ;將存儲器地址為R1的字數(shù)據(jù)讀入寄存器R0,
并將新地址R1+8寫入R1
LDR R0,[R1],R2 ;將存儲器地址為R1的字數(shù)據(jù)讀入寄存器R0,
并將新地址R1+R2寫入R1
LDR R0,[R1],R2,LSL #2 ;將存儲器地址為R1的字數(shù)據(jù)讀入寄存器R0,
并將新地址R1+R2*4寫入R1
【備注】注意事項:
a、立即數(shù)絕對值不大于4095的數(shù)值,可使用帶符號數(shù),即在-4095 ~ +4095之間。(4096D = 1000H)
b、語句的標號不能指向程序存儲器的程序存儲區(qū),而是指向程序存儲器的數(shù)據(jù)存儲區(qū)或數(shù)據(jù)存儲器的數(shù)據(jù)存儲區(qū)。另外指向的區(qū)域是可修改的。例如,在用戶模式下,有些存儲區(qū)是不能訪問的或是只讀的。
c、字傳送時,偏移量必須保證偏移的結(jié)果能夠使地址對齊。
d、使用寄存器移位的方法計算偏移量時。移位的位數(shù)不能超過規(guī)定的數(shù)值,而且不能用寄存器表示移位的位數(shù)。各類移位指令的移位位數(shù)規(guī)定如下:
ASR #n:算術右移(1≤n≤32)
LSL #n:邏輯左移(0≤n≤31)
LSR #n:邏輯右移(1≤n≤32)
ROR #n:循環(huán)右移(1≤n≤31)
e、R15作為基址寄存器Rn時,不可以使用回寫功能,即使用后綴“!”,另外,R15不可作為偏移寄存器使用。
5、字節(jié)數(shù)據(jù)加載/存儲指令:LDRB/STRB
LDRB指令用于從存儲器中將一個8位字節(jié)的數(shù)據(jù)加載到目的寄存器,同時將寄存器的高24位清零。該指令通常用于從存儲器中讀取8位的字節(jié)數(shù)據(jù)到通用寄存器,然后對數(shù)據(jù)進行處理。當程序計數(shù)器PC作為目的寄存器時,指令從存儲器讀取的數(shù)據(jù)被當做目的地,從而可以實現(xiàn)程序流程的跳轉(zhuǎn)
STRB指令用于從源寄存器中將一個8位的字節(jié)數(shù)據(jù)存儲到存儲器中,該字節(jié)數(shù)據(jù)為源寄存器的低8位,STRB指令和LDRB指令的區(qū)別在于數(shù)據(jù)的傳送方向。
LDRB R0,[R1] ;將存儲器地址為R1的字節(jié)數(shù)據(jù)讀入寄存器R0,
并將R0的高24位清零。
LDRB R0,[R1,#8] ;將存儲器地址為R1+8的字節(jié)數(shù)據(jù)讀入寄存器R0,
并將R0的高24位清零。
STRB R0,[R1] ;將寄存器R0中的字節(jié)數(shù)據(jù)寫入以R1為地址的存儲器中。
STRB R0,[R1,#8] ;將寄存器R0中的字節(jié)數(shù)據(jù)寫入以R1+8為地址的存儲器中。
6、LDRH/STRH 半字數(shù)據(jù)加載/存儲指令
31~28| 27~25| 24 23 22 21 20 | 19~16| 15~12| 11~8 | 7 6 5 4 | 3~0
cond | 000 | P U I W L | Rn | Rd | addr_H |1 S H 1 |addr_L
cond:指令執(zhí)行的條件編碼
I、P、U、W:用于區(qū)別不同的地址模式(偏移量)。I為0時,偏移量為8位立即數(shù),I為1時,偏移量為寄存器移位。P表示前/后變址,U表示加/減,W表示回寫。
L:L為1表示加載,L為0表示存儲。
S:用于區(qū)別有符號訪問(S為1)和無符號訪問(S為0)
H:用于區(qū)別半字訪問(H為1)或字節(jié)訪問(H為0)
Rd:源/目標寄存器
Rn:基址寄存器
addr H / addr I:表示偏移量,I為0時,偏移量為8位立即數(shù)由addr H和addr I組成;
I為1時,偏移量為寄存器移位addr H為0,addr L表示寄存器編號
LDR指令用于從寄存器中間一個16位的半字數(shù)據(jù)加載到目的寄存器Rd中,同時將寄存器的高16位清零,該指令通常用于從存儲器中讀取16位的半字數(shù)據(jù)到通用寄存器,然后對數(shù)據(jù)進行處理。當程序計數(shù)器PC作為目的寄存器時,指令從存儲器中讀取的數(shù)據(jù)被當做目的地址,從而可以實現(xiàn)程序流程的跳轉(zhuǎn)。
LDRH R0,[R1] ;將存儲器地址R1的半字數(shù)據(jù)讀入寄存器R0,
并將R0的高16位清零
LDRH R0,[R1,#8] ;將存儲器地址為R1+8的半字數(shù)據(jù)讀入寄存器R0,
并將R0的高16位清零
LDRH R0,[R1,R2] ;將存儲器地址為R1+R2的半字數(shù)據(jù)讀入寄存器R0,
并將R0的高16位清零
STRH R0,[R1] ;將寄存器R0中的半字數(shù)據(jù)寫入以R1為地址的存儲器中
使用半字加載/存儲指令需要注意的事項:
(1)必須半字地址對齊。
(2)對于R15的使用需要慎重,R15作為基址寄存器Rn時,不可以使用回寫功能,不可使用R15作為目的寄存器。
(3)立即數(shù)偏移使用的是8位無符號數(shù)。
(4)不能使用寄存器移位尋址
7、有符號數(shù)字節(jié)/半字加載指令:LDRSB / LDRSH
LDRSB指令用于從存儲器中間一個8位的字節(jié)數(shù)據(jù)加載到目的寄存器中,同時將寄存器的高24位設置為該字節(jié)數(shù)據(jù)的符號位的值,即將該8位字節(jié)數(shù)據(jù)進行符號位的擴展,生成32位數(shù)據(jù);LDRSH指令用于從存儲器中將一個16位的半字數(shù)據(jù)加載到目的寄存器Rd中,同時將寄存器的高16位設置為該字數(shù)據(jù)的符號位的值,即將該16位字數(shù)據(jù)進行符號位的擴展,生成32位數(shù)據(jù)。
LDRSB R0,[R1,#4] ;將存儲地址為R1+4的有符號字節(jié)數(shù)據(jù)讀入R0,
R0中的高24位設置為高字節(jié)數(shù)據(jù)的符號位
LDRSH R6,[R2],#2 ;將存儲地址為R2+2的有符號半字數(shù)據(jù)讀入R6,
R6的高16位設置成該字節(jié)數(shù)據(jù)的符號位,R2=R2+2
8、多寄存器加載和存儲指令:LDM / STM
LDM指令用于從基址寄存器所指示的一片連續(xù)存儲器中讀取數(shù)據(jù)到寄存器列表所指示的多個寄存器中,內(nèi)存單元的其實地址為基址寄存器Rn的值,各個寄存器有寄存器列表regs表示。該指令一般用于多個寄存器數(shù)據(jù)的出棧操作;STM指令用于將寄存器列表所指示的多個寄存器的值存入到由基址寄存器所指示的一片連續(xù)存儲器中,內(nèi)存單元的其實地址為基址寄存器Rn的值,各個寄存器由寄存器列表regs表示。指令的其它參數(shù)的用法和LDM指令是相同的。該指令一般用于多個寄存器數(shù)據(jù)的進棧操作。
type類型。用于數(shù)據(jù)的存儲和讀取有一下幾種情況:
IA 每次傳送后地址值加
IB 每次傳送前地址值加
DA 每次傳送后地址值減
DB 每次傳送前地址值減
對于堆棧操作有如下幾種情況:
FD 滿遞減堆棧
ED 空遞減堆棧
FA 滿遞增堆棧
EA 滿遞增堆棧
{ ! }為可選后綴,若選用該后綴,則當數(shù)據(jù)加載與存儲完畢后,將最后的地址寫入基址寄存器,否則基址寄存器的內(nèi)容不改變?;芳拇嫫鞑辉试S為R15,寄存器列表可以為R0~R15的任意組合。
{ ^ }為可選后綴,當治療為LDM且寄存器列表中包含R15,選用該后綴時表示:除了正常數(shù)據(jù)加載和存儲之外,還將SPSR復制到CPSR。同時,該后綴還表示傳入或傳出的是用戶模式下的寄存器,而不是當前模式下的寄存器。
LDMIA R0!,{R6-R8} ;R6 <- [R0],R7 <- [R0+4],R8 <- [R0+8],R0 <- R0+12
LDMIB R0!,{R6-R8} ;R6 <- [R0],R7 <- [R0+4],R8 <- [R0+8],R0 <- R0+8
9、堆棧和堆棧操作
堆棧就是在RAM存儲器中開辟(指定)的一個特定的存儲區(qū)域,在這個區(qū)域中,信息的存入(此時稱為推入)與取出(此時稱為彈出)的原則不再是“隨機存取”,而是按照“后進先出”的原則就行存取。
A】建棧:規(guī)定堆棧底部在RAM存儲器中的位置,如:用戶可以通過LDR命令設置SP的值來建立堆棧。
LDR R13,=0x90010 ;
LDR SP,=0x90010 ;
這時,SP指向地址0x90010,棧內(nèi)無數(shù)據(jù),堆棧底部與頂部重疊,是一個空棧。
B】進棧:STM指令配合FD(滿遞減)、ED(空遞減)、FA(滿遞增)、EA(空遞增)完成入棧操作。在使用一個堆棧的時候,需要確定堆棧在存儲器空間中是向上生長還是向下生長的。向上稱為遞增,向下稱為遞減。
STMFD SP!,{R2-R4} ;把R4,R3,R2的值依次壓棧(標號高的存在高地址)
LDMFD SP!,{R6-R8} ;把R2,R3,R4的值,依次退到R6,R7,R8
【備注】:
SWP交換指令,B指令,MRS/MSR指令,協(xié)處理器指令,偽指令等未補充,待更新。。。
評論