ARM 匯編尋址方式


ARM支持9種尋址方式:立即數尋址,寄存器尋址,寄存器偏移尋址,寄存器間接尋址,基址變址尋址,多寄存器尋址,相對尋址,堆棧尋址,塊拷貝尋址。

立即數尋址

將數據直接存放的指令中發給CPU,首先由於ARM的一條指令占了32bit,而操作碼本身也要占據一些位,所以留給立即數的位數肯定不到32bit,其次並不是滿足指定位數的數字都是立即數,ARM中的立即數必須可以通過某個8bit的數據經過循環右移得到

MOV R0,#255     ;R0 <- #255,#0~#255都是立即數
ADD R0, R0, #1  ;R0 <- (R0+#1)

寄存器直接尋址

將寄存器中的數據用作操作數

MOV R0, R1          ;R0 <- R1
ADD R0,R1, R2     ;R0 <- (R1 + R2)

寄存器間接尋址

將寄存器中的數據作為主存中操作數的地址,去到相應的主存地址取得操作數,用[R0]表示將R0中的數據當作操作數的地址...,[R0]!表示將R0中的數據當作操作數的地址並將操作后的結果地址給R0

LDR R0,[R1]        ;將R1指向的數據加載到R0中 
STR R0, [R1]!        ;將R0存儲的數據加載到R1指向的主存地址中,加載完畢R1中為操作后的地址
ADD R0,R1,[R2]

寄存器偏移尋址

現將寄存器的值進行移位,再將移位后的數據當作操作數

MOV R0,R2,LSL  #1   ;R2的值左移1位,結果賦給R0。
MOV R0,R2,LSL  R1 ;R2的值左移R1位,結果放入R0。

有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的值來填充,低端移出的位填入進位標志位。

寄存器基址變址尋址

可以看作寄存器間接尋址的增強版,不再直接從寄存器指向的地址中取操作數,而是從寄存器指向的地址再偏移一個量之后再取操作數

LDR R0,[R1,#4]    ;取R1的內容當作主存的地址,在此基礎上+4byte,從該地址處取操作數。
LDR R0,[R1,#4]!  ;同上,操作完畢后,!表示指令執行完畢把最后的數據地址寫到R1,即R1原來的地址+4
LDR R0,[R1,R2]    ;將寄存器R1的內容加上寄存器R2的內容形成操作數的地址,取得的操作數存入寄存器R0中。
STR R0, [R1,#-4];將R1中的數值減4作為地址,把R0中的數據存放到這個地址中。
LDR R0,[R1],#4   ;把R1指向的數據放到R0中,操作完成后[R1]自增4byte

批量寄存器尋址

LDMIA  R0,{R1,R2,R3,R4}     ;將R1,R2,R3,R4中的數據依次放入R0指向的內存地址,R0+4指向的內存地址...
LDMIA  R0,{R1-R4}  ;同上。

相對尋址

通過使用語句的中的標號進行尋址,通常配合跳轉指令使用

    BL   FCN  ;相對尋址,跳轉到NEXT處執行。
    ...
FCN:
    ...

堆棧尋址

堆棧即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棧
LDMFD  SP!,{R1-R7, PC} ;從FD棧中取得數據依次放入R1-R7,PC

塊拷貝尋址

塊拷貝尋址提供了一塊內存和一組寄存器之間的拷貝,按照內存使用方式的不同,可以分為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自動更新,指向操作后的地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM