ARM的九种寻址方式
文章目錄
- 1.立即數(shù)尋址
- 2.寄存器尋址
- 3.寄存器間接尋址
- 4.寄存器偏移尋址
- 5.寄存器基址變址尋址
- 6.批量寄存器尋址
- 7.相對尋址
- 8.堆棧尋址
- 9.塊拷貝尋址
尋址方式就是CPU根據(jù)指令中的地址信息,找出物理地址也就是內(nèi)存地址的方式,通俗理解就是ARM指出內(nèi)存地址的方式。
尋址的目的就是找出操作數(shù),比如ARM要做一個除法運(yùn)算,就需要除數(shù)和被除數(shù),除數(shù)和被除數(shù)都是除法指令的操作數(shù),要找到這些操作數(shù),可以有多種方法,尋找操作數(shù)的過程就叫做尋址。(我個人理解)
ARM支持九種尋址方式:
- 立即數(shù)尋址
- 寄存器尋址
- 寄存器偏移尋址
- 寄存器間接尋址
- 寄存器基址變址尋址
- 多寄存器尋址
- 相對尋址
- 堆棧尋址
- 塊拷貝尋址
1.立即數(shù)尋址
立即數(shù)尋址就是直接將內(nèi)存中的數(shù)據(jù)發(fā)給CPU作為操作數(shù)。注意,由于ARM是32位指令集,所以立即數(shù)的范圍不可以超出0255,也就是說立即數(shù)的范圍只能是0255。
格式:就是在立即數(shù)前面加上 # 來作為操作數(shù)
典型的例子就是直接對寄存器進(jìn)行寫值:
ldr r0, #254 ;將254寫入r0寄存器 add r1, r2, #3 ;將r2寄存器中的值與3相加后,在寫入r1寄存器2.寄存器尋址
寄存器尋址就是直接將寄存器中的數(shù)值作為操作數(shù):
ldr r1, r0 ;將r0寄存器中的值寫到r0 add r3, r2, r1 ;將r1、r2寄存器的值相加,結(jié)果寫入r3寄存器3.寄存器間接尋址
還是利用了寄存器,只不過操作數(shù)不是寄存器中的值了,操作數(shù)在內(nèi)存中,那怎么辦?沒事,操作數(shù)的地址就在寄存器中。所以寄存器間接尋址相當(dāng)于以寄存器中的值作為內(nèi)存地址,去內(nèi)存中尋找操作數(shù)。
格式:在提供操作數(shù)地址的寄存器上加上[],比如[r0]
mov r0, #0X54000032 ldr r1, [r0] ;將地址為0X54000032的數(shù)據(jù)寫入r1寄存器中4.寄存器偏移尋址
以寄存器尋址為本,將寄存器中的數(shù)移位后作為操作數(shù)。
一共有6中移位操作:
LSL:邏輯左移(Logical Shift Left),寄存器中字的低端空出的位補(bǔ)0。
LSR:邏輯右移(Logical Shift Right),寄存器中字的高端空出的位補(bǔ)0。
ASL:算術(shù)左移(Arithmetic Shift Left),和邏輯左移LSL相同。
ASR:算術(shù)右移(Arithmetic Shift Right),移位過程中符號位不變,即如果源操作數(shù)是正數(shù),則字的高端空出的位補(bǔ)0,否則補(bǔ)1。
ROR:循環(huán)右移(Rotate Right),由字的低端移出的位填入字的高端空出的位。
RRX:帶擴(kuò)展的循環(huán)右移(Rotate Right eXtended),操作數(shù)右移一位,高端空出的位用進(jìn)位標(biāo)志C的值來填充,低端移出的位填入進(jìn)位標(biāo)志位。
格式:rx, 移位命令 移位操作數(shù)
ldr r0, r1, lsl #3 ;將r1的值邏輯左移3位后寫入r0 ldr r0, r1, ror r2 ;將r1的值循環(huán)右移r2中的值對應(yīng)位后,寫入r05.寄存器基址變址尋址
基址變址尋址是基于寄存器間接尋址的,只不過地址不再是寄存器中的值了,而是偏移后的值,這里的偏移值可以理解為地址相加值。
加上感嘆號應(yīng)該有優(yōu)先執(zhí)行的意思吧(個人理解)
格式:[rx, n],表示在rx寄存器所指向的地址上,再偏移(相加)n字節(jié)
ldr r0, [r1, #3] ;地址為:r1值+3字節(jié),指令執(zhí)行完r1不變 ldr r0, [r1, #3]! ;地址為:r1值+3字節(jié),指令執(zhí)行完r1+3 ldr r0, [r1, #-1] ;地址為:r1值-1字節(jié),指令執(zhí)行完r1不變 ldr r0, [r1, r2] ;地址為:r1值+r2值 ldr r0, [r1], #4 ;地址為:r1值,但指令執(zhí)行完后,r1值+4字節(jié)6.批量寄存器尋址
批量寄存器尋址就是使用一個大括號{}包含多個寄存器
ldmia r0, {r1, r2, r3, r4} ;將r1,r2,r3,r4中的數(shù)據(jù)依次放入R0指向的內(nèi)存地址,r0+4指向的內(nèi)存地址... ldmia r0, {r1-r4} ;同上。7.相對尋址
通過標(biāo)號進(jìn)行尋址,經(jīng)常與跳轉(zhuǎn)指令相配合使用
bl heihei heihei: ;跳轉(zhuǎn)到heihei執(zhí)行8.堆棧尋址
堆棧即Stack,因?yàn)镃PU的寄存器總是及其有限的,很多時候我們不得不使用內(nèi)存來存儲數(shù)據(jù),比如進(jìn)行多級跳轉(zhuǎn)的時候,這時候堆棧就是一個很好的工具,每次跳轉(zhuǎn)就將當(dāng)前函數(shù)的返回地址存儲到內(nèi)存,最底層被調(diào)用的子函數(shù)會最先返回,就先將壓入棧的現(xiàn)場返回,以此類推…,ARM使用SP(R13)作為棧指針,ARM設(shè)計的內(nèi)存棧模型有2×2=4種
按照棧在內(nèi)存增長的方向分為遞增棧和遞減棧 :
遞增(Increase) 堆棧:向堆棧寫入數(shù)據(jù)時,堆棧由低地址向高地址生長。
遞減(Descend) 堆棧:向堆棧寫入數(shù)據(jù)時,堆棧由高地址向低地址生長。
根據(jù)堆棧指針SP指向的位置,又可以把堆棧分為滿堆棧和空堆棧兩種。
滿堆棧(Full Stack):SP始終指向棧頂元素,壓棧的時候先移動SP,再將數(shù)據(jù)放入SP指向的地址。
空堆棧(Empty Stack):SP始終指向下一個將要放入元素的位置,壓棧時先將數(shù)據(jù)放入SP指向的地址,再移動SP
最后,可以得到4種基本的堆棧類型:
滿增棧(FA):堆棧指針指向最后壓入的數(shù)據(jù),且由低地址向高地址生長。
滿減棧(FD):堆棧指針指向最后壓入的數(shù)據(jù),且由高地址向低地址生長。常用這種
空增棧(EA):堆棧指針指向下一個將要壓入數(shù)據(jù)的地址,且由低地址向高地址生長。
空減棧(ED):堆棧指針指向下一個將要壓入數(shù)據(jù)的地址,且由高地址向低地址生長。
stmfd sp!, {r1-r7, lr} ;將r1到r7和lr的數(shù)據(jù)壓入fd棧9.塊拷貝尋址
塊拷貝尋址提供了一塊內(nèi)存和一組寄存器之間的拷貝,按照內(nèi)存使用方式的不同,可以分為2×2=4種。地址增方向/地址減方向×先偏移/后偏移。堆棧尋址就可以看作是塊拷貝尋址的的一個實(shí)例。
即:
IB:Increment Before Operating
IA:Increment After Operating
DB:Decrement Before Operating
DA:Decrement After Operating
STMIA R0!,{R1—R7} ;將R1-R7的寄存器中的值放入R0指向的地址,R0自動更新,指向操作后的地址參考
總結(jié)
以上是生活随笔為你收集整理的ARM的九种寻址方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022南京商业贷款提前还款
- 下一篇: 回溯法之旅行商问题解题思路详解