1.19.ARM彙編指令集7之儲存器訪問指令(LDR和STR)
ARM彙編指令集的儲存器訪問指令: LDR & STR & LDM & STM & SWP
這裡先總的介紹一下儲存器訪問指令,然後再詳解說前兩個(LDR&STR)
ARM儲存器訪問指令:
ARM處理器是載入/儲存體系結構的典型的RISC處理器,對儲存器的訪問只能使用載入和儲存指令實現。ARM的載入/儲存指令可以實現字、半字、有符號和無符號數字節的操作。批量載入/儲存指令可實現一條指令載入/儲存多個暫存器的內容,大大提高了效率。SWP指令是一條暫存器和儲存器內容交換的指令,可用於訊號量操作等。ARM處理器是馮諾依曼儲存結構,程式空間、RAM及IO對映空間統一編址,除了對RAM操作以外,對外圍IO、程式資料的訪問均要通過載入/儲存指令進行。
* LDR & STR
載入/儲存字和無符號位元組指令,使用單一資料傳送指令(STR和LDR)來裝載和儲存單一位元組或字的資料到內容。LDR指令用於從記憶體中讀取資料放入暫存器中,STR指令用於將暫存器中的資料儲存到記憶體中。
指令格式:
LDR{cond}{T} Rd,<地址> ; 載入指定地址上的資料(字),放入Rd中
STR{cond}{T} Rd,<地址> ; 儲存資料(字)到指定地址的儲存單元,要儲存的資料在Rd中
LDR{cond}B{T} Rd,<地址> ; 載入位元組資料放入Rd中,即Rd最低位元組有效,高24位清零
STR{cond}B{T} Rd,<地址> ; 儲存位元組資料,要儲存的資料在Rd中,最低位元組有效
注:上面說的T為可選後綴,若指令有T,那麼即使處理器是在特權模式下,儲存系統也將訪問看成是處理器是在使用者模式下,T在使用者模式下無效,不能與前索引偏移一起使用T。
LDR/STR指令定址非常靈活,它由兩部分組成,一部分為一個基址暫存器,可以為任一個通用暫存器;另一部分為一個地址偏移量。地址偏移量有以下3種格式:
①立即數
立即數可以是一個無符號數值,這個資料可以加到基址暫存器,也可以從基址暫存器中減去這個數值。
eg:
LDR R1,[R0,#0x12] ; 將R0+0x12地址的資料讀出,儲存到R1中(R0的值不變)
LDR R1,[R0,#-0x12] ; 將R0-0x12地址處的資料讀出,儲存到R1中(R0的值不變)
LDR R1,[R0] ; 將R0地址處的資料讀出,儲存到R1中(零偏移)
②暫存器
暫存器中的數值可以載入到基址暫存器,也可以從基址暫存器中減去這個數值。
eg:
LDR R1,[R0,R2] ; 將R0+R2地址的資料讀出,儲存在R1中(R0的值不變)
LDR R1,[R0,-R2] ; 將R0-R2地址的資料讀出,儲存在R1中(R0的值不變)
③暫存器及移位常數
暫存器移位後的值可以加到基址暫存器,也可以從基址暫存器中減去這個數值。
LDR R1,[R0,R2,LSL #2] ; 將R0+R2*4地址處的資料讀出,儲存到R1中(R0和R2的值不變)
LDR R1,[R0,-R2,LSL #2] ; 將R0-R2*4地址處的資料讀出,儲存到R1中(R0和R2的值不變)
從定址方式的地址計算方法分,載入/儲存指令有以下4中形式:
①零偏移
Rn的值作為傳送資料的地址,即地址偏移量為0。
eg:
LDR Rd,[Rn]
②前索引偏移
在資料傳送之前,將偏移量加到Rn中,其結果作為傳送資料的儲存地址,若使用字尾“!”,則結果寫回到Rn中,且Rn值不允許是R15。
eg:
LDR Rd,[Rn,#0x04]!
LDR Rd,[Rn,#-0x04]
③程式相對偏移
程式相對偏移是索引形式的另一個版本,彙編器由PC暫存器計算偏移量,並將PC暫存器作為Rn生成前索引指令,不能使用字尾“!”。
eg:
LDR Rd,label ; label為程式標號,label必須是在當前指令的±4KB範圍內
④後索引偏移
Rn的值用作傳送資料的儲存地址,在資料傳送後,將偏移量與Rn相加,結果寫回到Rn中,Rn不允許是R15。
eg:
LDR Rd,[Rn],#0x04
* 注:關於地址對準問題:大多數情況下,必須保證用於32位傳送的地址是32位對準的。
* 注:關於半字/有符號數等操作都與上述類似,使用時參考上面的即可。
* 注:LDR/STR 指令用於對記憶體變變數的訪問,記憶體緩衝區資料的訪問、查表、外圍部件的控制操作等等,若使用LDR指令載入資料到PC暫存器,則實現程式跳轉功能。