第二部分 ARM指令集翩迈、尋址方式
1. ARM指令集
ARM指令字長(zhǎng)為固定的32位返十。一條典型的ARM指令編碼格式如下:ARM指令集大致可分為一下6大類:跳轉(zhuǎn)指令持灰、數(shù)據(jù)處理指令、程序狀態(tài)寄存器指令负饲、Load/Store指令堤魁、協(xié)處理器指令和中斷指令等。
1. 數(shù)據(jù)處理指令
? ? ? ? 數(shù)據(jù)處理指令又可細(xì)分為移動(dòng)指令妥泉、算術(shù)指令、邏輯運(yùn)算指令洞坑、比較運(yùn)算指令和乘法指令盲链。
1.1 移動(dòng)指令
最簡(jiǎn)單的ARM指令,如:
mov r9, sp
mov r1 #0
1.2 移位器
共有5中移位操作:邏輯左移LSL迟杂、邏輯右移LSR刽沾、算術(shù)右移ASR、循環(huán)右移ROR和擴(kuò)展的循環(huán)右移RRX排拷。
如:r1 = r1<<9
mov r1, r1, LSL #9
1.3 算術(shù)指令
32位有符號(hào)數(shù)和無符號(hào)數(shù)的加減法侧漓,常用算術(shù)指令有:
ADC | 帶進(jìn)位的加法 | Rd = Rn + N + carry |
---|---|---|
ADD | 加法 | Rd = Rn + N |
RSB | 反向減法 | Rd = N - Rn |
RSC | 帶借位的反向減法 | Rd = N - Rn - !(carry flag) |
SBC | 帶借位的減法 | Rd = Rn - N - !(carry flag) |
SUB | 減法 | Rd = Rn - N |
如:S_FRAME_SIZE是72,r0 = sp + 72
r0 = r1 + (r1<<2)
add r0, sp, #S_FRAME_SIZE
add r0, r1, r1, LSL #2
1.4 邏輯運(yùn)算指令
AND | 與 | Rd = Rn & N |
---|---|---|
ORR | 或 | Rd = Rn | N |
EOR | 異或 | Rd = Rn ^ N |
BIC | 清位 | Rd = Rn & ~N |
如:
and r1, r0, #0x1f
1.5 比較指令
常見比較指令有:
CMN | 否定比較 | Rn + N |
---|---|---|
CMP | 比較 | Rn - N |
TEQ | 測(cè)試兩個(gè)32位數(shù)是否相等 | Rn ^ N |
TST | 測(cè)試一個(gè)32位數(shù)的位 | Rn & N |
如:比較r1是否等于0x1a监氢,并設(shè)定cpsr中的標(biāo)志位布蔗,這樣后面的指令可以根據(jù)標(biāo)志位條件執(zhí)行。
teq r1, 0x1a
1.6 乘法指令
常見乘法指令有:
MLA | 乘法和累加 | Rd = Rm * Rs + Rn |
---|---|---|
MUL | 乘法 | Rd = Rm * Rs |
如:r3 = r4 * r1 + r3
mla r3, r4, r1, r3
2. 跳轉(zhuǎn)指令
? ? ? ? 改變程序執(zhí)行流程或者用于調(diào)用子程序忙菠,強(qiáng)制程序計(jì)數(shù)器PC指向一個(gè)新地址何鸡。常用的跳轉(zhuǎn)指令有:
B | 跳轉(zhuǎn) |
---|---|
BL | 帶返回的跳轉(zhuǎn) |
BX | 跳轉(zhuǎn)并切換狀態(tài) |
BLX | 帶返回的跳轉(zhuǎn)并切換狀態(tài) |
如:
bl cpu_init_cp15
3. 軟中斷指令
常用的軟中斷指令如下:
SWI | 軟中斷 |
---|
4. 程序狀態(tài)寄存器指令
常用程序狀態(tài)寄存器指令如下:
MRS | 復(fù)制程序狀態(tài)寄存器到通用寄存器中 | Rd = psr |
---|---|---|
MSR | 將通用寄存器的值傳到程序狀態(tài)寄存器中 | psr[field] = Rm |
MSR | 將立即數(shù)的值傳到程序狀態(tài)寄存器中 | psr[field] = 立即數(shù) |
5. 協(xié)處理器指令
協(xié)處理器是指令集的擴(kuò)展,協(xié)處理器既可以提供額外的計(jì)算能力牛欢,也用于包括Cache和存儲(chǔ)管理在內(nèi)的存儲(chǔ)系統(tǒng)骡男。協(xié)處理器指令包括數(shù)據(jù)處理、寄存器傳輸和內(nèi)存?zhèn)鬏斨噶睢?br> 常用協(xié)處理器指令如下:
CDP | 協(xié)處理器數(shù)據(jù)傳輸——在協(xié)處理器中執(zhí)行一個(gè)操作 |
---|---|
MRC|MCR | 協(xié)處理器寄存器傳輸——從協(xié)處理器中移出數(shù)據(jù)或者移入數(shù)據(jù) |
LDC STC | 協(xié)處理器內(nèi)存?zhèn)鬏敗獜膮f(xié)處理器中l(wèi)oad/store內(nèi)存 |
5. 偽指令
加載常量的偽指令如下:
LDR | 加載常量的偽指令 | Rd = 32位的常量 |
---|---|---|
ADR | 加載地址的偽指令 | Rd = 32位的相對(duì)地址 |
如:
adr lr, here
2. ARM尋址方式
? ? ? ? 尋址方式是指處理器根據(jù)指令中給出的地址信息來尋找物理地址的方式傍睹,目前ARM指令系統(tǒng)支持以下幾種尋址方式:
2.1 立即尋址
也稱為立即數(shù)尋址隔盛,這種尋址方式指令中就已經(jīng)給出了操作數(shù)。也就是在執(zhí)行指令的過程中拾稳,處理器取得指令的同時(shí)也取得了操作數(shù)吮炕,因此稱為立即數(shù)尋址。例如:
ADD R0, #1 @R0+1->R0
ADD R0, R0, #0x3F @R0+0x3F->R0
在上面兩條指令中访得,源操作數(shù)就是立即數(shù)龙亲,要求以“#”開始陕凹,對(duì)于十六進(jìn)制的立即數(shù),要求在“#”后面加“0x”或“&”鳄炉。
2.2 寄存器尋址
即將寄存器中的數(shù)值作為操作數(shù)杜耙,是各類微處理器常用的尋址方式,也是效率較高的尋址方式拂盯。例如:
ADD R0, R1, R2 @ R1+R2->R0
該指令的執(zhí)行效果是將R1和R2的值相加佑女,將結(jié)果存入R0
2.3 寄存器間接尋址
寄存器間接尋址是以寄存器中的值作為操作數(shù)的地址,操作數(shù)本身存放在寄存器中谈竿。例如:
ADD R0, R1, [R2] @ R1+[R2]->R0
LDR R0, [R1] @ [R1]->R0
第一條指令团驱,以寄存器R2的值作為操作數(shù)的地址,在寄存器中取得一個(gè)操作數(shù)后與R1相加空凸,將結(jié)果存入寄存器R0嚎花。第二條指令,將寄存器中以R1為地址的值賦給R0劫恒。
2.4 基址變址尋址
基址變址尋址是把基址寄存器的內(nèi)容與指令中給出的地址偏移量相加贩幻,從而得到一個(gè)操作數(shù)的有效地址。該方式常用于訪問基地址附近的某些存儲(chǔ)單元两嘴,一般有以下幾種方式:
LDR R0, [R1, #4] @ [R1+4]->R0
第一條指令,將寄存器R1的值加上4作為操作數(shù)的有效地址族壳,取得操作數(shù)后存入R0中憔辫。
LDR R0, [R1, #4]! @ [R1+4]->R0、R1+4->R1
第二條指令仿荆,將寄存器R1的值加上4作為操作數(shù)的有效地址贰您,取得操作數(shù)后存入R0中,然后寄存器R1的值加上4個(gè)字節(jié)拢操。
LDR R0, [R1]锦亦, #4 @ [R1]->R0、R1+4->R1
第三條指令令境,將寄存器R1的值作為操作數(shù)的有效地址杠园,取得操作數(shù)后存入R0中,然后寄存器R1的值加上4個(gè)字節(jié)舔庶。
LDR R0, [R1, R2] @ [R1+R2]->R0
第四條指令抛蚁,將寄存器R1和R2的值相加作為操作數(shù)的有效地址,取得操作數(shù)后存入R0中惕橙。
2.5 多寄存器尋址
使用多寄存器尋址瞧甩,一條指令可以完成多個(gè)寄存器值的傳送,一條指令最多可以傳送16個(gè)通用寄存器的值弥鹦。例如:
LDMIA R0, {R1,R2,R3,R4,} @ [R0]->R1,[R0+4]->R2,[R0+8]->R3,[R0+12]->R4
該指令后綴IA表示每次執(zhí)行完讀取/存儲(chǔ)操作后肚逸,R0按字長(zhǎng)增加,因此,指令可以將連續(xù)存儲(chǔ)單元的值傳送到R1~R4朦促。
2.6 相對(duì)尋址
與基址變址尋址類似膝晾,相對(duì)尋址以程序計(jì)數(shù)器PC的當(dāng)前值作為基地址,指令中的地址標(biāo)號(hào)作為偏移量思灰,將兩者相加后得到操作數(shù)的有效地址玷犹。以下程序完成子程序的調(diào)用和返回,跳轉(zhuǎn)指令BL采用了相對(duì)尋址方式:
BL NEXT @ 跳轉(zhuǎn)到子程序NEXT處執(zhí)行指令
......
NEXT
......
MV PC, LR @ 從子程序返回
2.7 堆棧尋址
? ? ? ? 堆棧是一種數(shù)據(jù)結(jié)構(gòu)洒疚,按先進(jìn)后出的方式工作歹颓,使用一個(gè)稱為堆棧指針的專用寄存器指示當(dāng)前的操作,堆棧指針總是指向堆棧頂端油湖。當(dāng)堆棧指針指向最后壓入的數(shù)據(jù)時(shí)巍扛,稱為滿堆棧;當(dāng)堆棧指針指向下一個(gè)將要壓入的位置時(shí)乏德,稱為空堆棧撤奸。
? ? ? ? 根據(jù)堆棧的生成方式,可分為遞增堆棧和遞減堆棧喊括。當(dāng)堆棧由低地址向高地址生成時(shí)胧瓜,稱為遞增堆棧,反之稱為遞減堆棧郑什。排列組合后可得到4中類型的堆棧工作方式府喳,ARM微處理器支持全部4種類型的堆棧工作方式。具體如下:
滿遞增堆棧:堆棧指針指向最后壓入的數(shù)據(jù)蘑拯,由低地址向高地址生成钝满。
滿遞減堆棧:堆棧指針指向最后壓入的數(shù)據(jù),由高地址向低地址生成申窘。
空遞增堆棧:堆棧指針指向下一個(gè)將要壓入數(shù)據(jù)的空位置弯蚜,由低地址向高地址生成。
空遞減堆棧:堆棧指針指向下一個(gè)將要壓入數(shù)據(jù)的空位置剃法,由高地址向低地址生成碎捺。