日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ARM的九种寻址方式

發布時間:2023/12/16 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ARM的九种寻址方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1.立即數尋址
  • 2.寄存器尋址
  • 3.寄存器間接尋址
  • 4.寄存器偏移尋址
  • 5.寄存器基址變址尋址
  • 6.批量寄存器尋址
  • 7.相對尋址
  • 8.堆棧尋址
  • 9.塊拷貝尋址

尋址方式就是CPU根據指令中的地址信息,找出物理地址也就是內存地址的方式,通俗理解就是ARM指出內存地址的方式。

尋址的目的就是找出操作數,比如ARM要做一個除法運算,就需要除數和被除數,除數和被除數都是除法指令的操作數,要找到這些操作數,可以有多種方法,尋找操作數的過程就叫做尋址。(我個人理解)

ARM支持九種尋址方式:

  • 立即數尋址
  • 寄存器尋址
  • 寄存器偏移尋址
  • 寄存器間接尋址
  • 寄存器基址變址尋址
  • 多寄存器尋址
  • 相對尋址
  • 堆棧尋址
  • 塊拷貝尋址

1.立即數尋址

立即數尋址就是直接將內存中的數據發給CPU作為操作數。注意,由于ARM是32位指令集,所以立即數的范圍不可以超出0255,也就是說立即數的范圍只能是0255。

格式:就是在立即數前面加上 # 來作為操作數

典型的例子就是直接對寄存器進行寫值:

ldr r0, #254 ;將254寫入r0寄存器 add r1, r2, #3 ;將r2寄存器中的值與3相加后,在寫入r1寄存器

2.寄存器尋址

寄存器尋址就是直接將寄存器中的數值作為操作數:

ldr r1, r0 ;將r0寄存器中的值寫到r0 add r3, r2, r1 ;將r1、r2寄存器的值相加,結果寫入r3寄存器

3.寄存器間接尋址

還是利用了寄存器,只不過操作數不是寄存器中的值了,操作數在內存中,那怎么辦?沒事,操作數的地址就在寄存器中。所以寄存器間接尋址相當于以寄存器中的值作為內存地址,去內存中尋找操作數。

格式:在提供操作數地址的寄存器上加上[],比如[r0]

mov r0, #0X54000032 ldr r1, [r0] ;將地址為0X54000032的數據寫入r1寄存器中

4.寄存器偏移尋址

以寄存器尋址為本,將寄存器中的數移位后作為操作數。

一共有6中移位操作:

LSL:邏輯左移(Logical Shift Left),寄存器中字的低端空出的位補0。

LSR:邏輯右移(Logical Shift Right),寄存器中字的高端空出的位補0。

ASL:算術左移(Arithmetic Shift Left),和邏輯左移LSL相同。

ASR:算術右移(Arithmetic Shift Right),移位過程中符號位不變,即如果源操作數是正數,則字的高端空出的位補0,否則補1。

ROR:循環右移(Rotate Right),由字的低端移出的位填入字的高端空出的位。

RRX:帶擴展的循環右移(Rotate Right eXtended),操作數右移一位,高端空出的位用進位標志C的值來填充,低端移出的位填入進位標志位。

格式:rx, 移位命令 移位操作數

ldr r0, r1, lsl #3 ;將r1的值邏輯左移3位后寫入r0 ldr r0, r1, ror r2 ;將r1的值循環右移r2中的值對應位后,寫入r0

5.寄存器基址變址尋址

基址變址尋址是基于寄存器間接尋址的,只不過地址不再是寄存器中的值了,而是偏移后的值,這里的偏移值可以理解為地址相加值。

加上感嘆號應該有優先執行的意思吧(個人理解)

格式:[rx, n],表示在rx寄存器所指向的地址上,再偏移(相加)n字節

ldr r0, [r1, #3] ;地址為:r1值+3字節,指令執行完r1不變 ldr r0, [r1, #3]! ;地址為:r1值+3字節,指令執行完r1+3 ldr r0, [r1, #-1] ;地址為:r1值-1字節,指令執行完r1不變 ldr r0, [r1, r2] ;地址為:r1值+r2值 ldr r0, [r1], #4 ;地址為:r1值,但指令執行完后,r1值+4字節

6.批量寄存器尋址

批量寄存器尋址就是使用一個大括號{}包含多個寄存器

ldmia r0, {r1, r2, r3, r4} ;將r1,r2,r3,r4中的數據依次放入R0指向的內存地址,r0+4指向的內存地址... ldmia r0, {r1-r4} ;同上。

7.相對尋址

通過標號進行尋址,經常與跳轉指令相配合使用

bl heihei heihei: ;跳轉到heihei執行

8.堆棧尋址

堆棧即Stack,因為CPU的寄存器總是及其有限的,很多時候我們不得不使用內存來存儲數據,比如進行多級跳轉的時候,這時候堆棧就是一個很好的工具,每次跳轉就將當前函數的返回地址存儲到內存,最底層被調用的子函數會最先返回,就先將壓入棧的現場返回,以此類推…,ARM使用SP(R13)作為棧指針,ARM設計的內存棧模型有2×2=4種

按照棧在內存增長的方向分為遞增棧遞減棧

遞增(Increase) 堆棧:向堆棧寫入數據時,堆棧由低地址向高地址生長。

遞減(Descend) 堆棧:向堆棧寫入數據時,堆棧由高地址向低地址生長。

根據堆棧指針SP指向的位置,又可以把堆棧分為滿堆棧空堆棧兩種。

滿堆棧(Full Stack):SP始終指向棧頂元素,壓棧的時候先移動SP,再將數據放入SP指向的地址。

空堆棧(Empty Stack):SP始終指向下一個將要放入元素的位置,壓棧時先將數據放入SP指向的地址,再移動SP

最后,可以得到4種基本的堆棧類型:

滿增棧(FA):堆棧指針指向最后壓入的數據,且由低地址向高地址生長。

滿減棧(FD):堆棧指針指向最后壓入的數據,且由高地址向低地址生長。常用這種

空增棧(EA):堆棧指針指向下一個將要壓入數據的地址,且由低地址向高地址生長。

空減棧(ED):堆棧指針指向下一個將要壓入數據的地址,且由高地址向低地址生長。

stmfd sp!, {r1-r7, lr} ;將r1到r7和lr的數據壓入fd棧

9.塊拷貝尋址

塊拷貝尋址提供了一塊內存和一組寄存器之間的拷貝,按照內存使用方式的不同,可以分為2×2=4種。地址增方向/地址減方向×先偏移/后偏移。堆棧尋址就可以看作是塊拷貝尋址的的一個實例。

即:

IB:Increment Before Operating

IA:Increment After Operating

DB:Decrement Before Operating

DA:Decrement After Operating

STMIA R0!,{R1—R7} ;將R1-R7的寄存器中的值放入R0指向的地址,R0自動更新,指向操作后的地址

參考

總結

以上是生活随笔為你收集整理的ARM的九种寻址方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。