資訊推薦:嵌入式:Load/Store之單寄存器的存取指令

2022-12-21 14:17:51 來源:51CTO博客

ARM處理器是Load/Store型的,即它對數據的操作是通過將數據從存儲器加載到片內寄存器中進行處理,處理完成后的結果經過寄存器存回到存儲器中,以加快對片外存儲器進行數據處理的速度。


(相關資料圖)

ARM的數據存取指令Load/Store是唯一用于寄存器和存儲器之間進行數據傳送的指令。

在ARM系統中I/O操作是通過存儲器映射進行尋址的,對I/O設備的操作可以和對存儲器的操作一樣,因此,也是使用Load/Store指令完成。

Load/Store指令分類

ARM指令集中有三種基本的數據存取指令:

單寄存器的存取指令(LDR,STR):提供寄存器和存儲器之間最靈活的單數據項傳送方式,傳送的數據可以是8位字節、16位半字或32位字。多寄存器存取指令(LDM,STM):可有效地用于大批數據的傳送。一般這些指令用于進程的進入和退出,保存和恢復工作寄存器以及拷貝存儲器中一塊數據。單寄存器交換指令(SWP):用于寄存器和存儲器中的數據交換。在一個指令中完成存取操作。該指令常用來完成信號量操作,而信號量是一種解決進程同步和互斥問題的機制。
單寄存器的存取指令

單寄存器存取指令是ARM在寄存器和存儲器間傳送單個字節和字的最靈活方式。根據傳送數據的類型不同,單個寄存器存取指令又可以分為以下兩類:

單字和無符號字節的數據傳送指令半字和有符號字節的數據傳送指令
1、單字和無符號字節的數據傳送指令

這一類數據傳送指令的編碼格式如下:

指令說明

基址寄存器加上或減去一個無符號立即數或者 寄存器偏移量構成存儲器訪問地址。當從存儲器讀取一個無符號字節數據時,需要將它用0擴展到32位,然后放置到目的寄存器中。當從一個寄存器向存儲器寫一個字節的數據時,寫的是寄存器的低8位。前變址的尋址模式使用計算出的地址作為存儲器地址進行數據存取操作,然后,當要求回寫(W=1)(即自動變址方式),將基址寄存器更新為計算出的地址值。后變址的尋址模式用未修改的基址寄存器來傳送數據,然后將基址寄存器更新為計算出的地址,而不管W位如何。

指令匯編格式

前變址格式

LDR|STR {} {B} Rd, [Rn, ] {!}

? 其中B表示是按字節傳送,缺省時按字傳送,offset可能是±12位立即數,或者±Rm{},這里shift包括移位方式和移位位數,移位位數只能是5位立即數,而不能再來自于寄存器Rs。根據有無{!}選擇是否回寫(自動變址)。后變址格式

LDR|STR {} {B} {T} Rd, [Rn],

? 其中T標志只能在非用戶模式(即特權模式)下使用,作用是選擇用戶角度的存儲器訪問。相對PC的形式

LDR|STR {} {B} Rd, LABEL

舉例:

LDR  R8,[R10]   ;R8←[R10]LDRNE R1,[R5,#960]!  ;(有條件地)R1←[R5+960],R5 ←R5+960STR  R2,[R9,#consta-struc] ;consta-struc是常量表達式,范圍為-4095~4095STRB R0,[R3,-R8,ASR #2] ;R0→[R3-R8÷4],存儲R0的最低有效字節,但R3和R8的內容不變LDR  R1,localdata   ;加載一個字,該字位于標號localdata所在地址。(相對PC形式)LDR  R0,[R1],R2,LSL #2 ;將地址為R1的內存單元數據讀取到R0中,然后R1←R1+R2*4LDRB R0,[R2,#3] ;將內存單元(R2+3)中的字節數據讀到R0中,R0的高24位被設置為0LDR  R1,[R0,-R2,LSL #2] ;將R0-R2*4地址處的數據讀出,保存到R1中,R0,R2的值保持不變。STR  R0,[R7],#-8   ;將R0的內容存到R7中地址對應的內存中,R7←R7-8

在編程中,常使用相對PC的形式將R0中的一個字存到外設UART,如:

LDR    R1,UARTADD       STR     R0,[R1]

或者,使用相對PC形式將外設UART數據讀到R0 ,如:

LDR    R1,UARTADD       LDR    R0,[R1]

注意:

這里UARTADD標號在附近4KB范圍之內。

使用PC作為基址時,得到的傳送地址為當前指令地址加8字節;PC不能用作偏移寄存器,也不能用于任何自動變址尋址模式(包括后變址模式)。

把一個字讀到PC可以使程序轉移到讀取的地址,從而實現程序跳轉。但應避免將一個字節讀取到PC。應盡量避免把PC存儲到存儲器,因為不同處理器可能會產生不同的結果。

只要不使用自動變址,Rd=Rn是可以的,但在一般情況下,Rd、Rn和Rm應是不同的。

2、半字和有符號字節的數據傳送指令

有符號的字節或半字的傳送用“符號位”擴展到32位。無符號半字的傳送用0擴展到32位。這類數據傳送的二進制編碼如下:

立即數偏移量只能8位之內。寄存器偏移量不可移位得到。S、H用于定義所傳送的數據類型。

S

H

數據類型

1

0

有符號字節

0

1

無符號半字

1

1

有符號半字

指令匯編格式

這一類數據傳送指令的匯編格式如下:

前變址格式

LDR|STR{ } H|SH|SB  Rd,  [Rn, ]{!}

后變址格式

LDR|STR {} H|SH|SB  Rd,  [Rn], 

式中是#±<8位立即數>或#±Rm;H|SH|SB選擇傳送數據類型;其它部分的匯編器格式與傳送字和無符號字節相同。所有半字傳送應使用半字對齊的地址。

舉例:

LDREQSH  R11,[R6];(有條件地) R11←[R6],加載16位半字,有符號擴展到32位LDRH R1,[R0,#20]! ;R1←[R0+20],加載16位半字,0擴展到32位STRH  R4,[R3,R2] ;R4→[R3+R2],存儲最低的有效半字到R3+R2LDRSB R0,const ;加載位于標號const地址的字節,有符號擴展LDRH  R6,[R2],#2 ;將R2地址上的半字數據讀出到R6,高16位用0擴展,R2=R2+2LDRSH  R1,[R9];將R9地址上的半字數據讀取到R1中,高16位用符號位擴展STRNEH  R0,[R2,#960] ;(有條件地)將R0的內容送到(R2+960)的內存中,R2=R2+960

參考文獻:

孟祥蓮.嵌入式系統原理及應用教程(第2版)[M].北京:清華大學出版社,2017.

標簽: 數據傳送指令 基址寄存器 數據存取

上一篇:天天觀天下!構建超媒體驅動的 RESTful Web 服務
下一篇:精華推薦 |【深入淺出Sentinel原理及實戰】「原理探索專題」完整剖析Alibaba微服務架構體系之輕量級高可用流量控制組件Sentinel(1)