新聞中心

很好的 ARM指令集解析

作者: 時(shí)間:2016-11-21 來(lái)源:網(wǎng)絡(luò) 收藏

ARM指令和指令系統(tǒng)

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



關(guān)鍵詞: ARM指令集解

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉