ARM指令集【 PUSH \POP】【跳轉B\BL\BX\BLX \BXJ】【資料操作LDR\LDRB\LDRH\LDM\STR\STRB\STRH\STM】【移位LSL/LSR/ASL/ASR】

城東發表於2018-09-10

官方文件指令集概述:
在這裡插入圖片描述
具體的指令集介紹:
在這裡插入圖片描述

PUSH and POP

本部落格摘錄於:http://blog.sina.com.cn/s/blog_95baef7b01014ub4.html
示例 :
PUSH {R4,LR}
將低暫存器R4入棧,LR也入棧。
POP {R4,PC}
將堆疊中的資料彈出到低暫存器 R4 及 PC 中
說明 :
暫存器入棧及出棧指令.實現低暫存器和可選的 LR 暫存器入棧暫存器和可選的 PC暫存器出棧操作,堆疊地 址由 SP 寄存設定,堆疊是滿遞減堆疊.指令格式如下;
PUSH {reglist[,LR]}
POP {reglist[,PC]}
其中 reglist 入棧/出棧低暫存器列表,即 R0~R7
LR 入棧時的可選暫存器
PC 出棧時的可選暫存器
暫存器入棧及出棧指令舉例如下;
PUSH {R0-R7,LR} ;將低暫存器 R0~R7 全部入棧,LR 也入棧
POP {R0-R7,PC} ;將堆疊中的資料彈出到低暫存器 R0~R7 及 PC 中
滿遞減堆疊 含義可參照如下:
堆疊定址
堆疊是特定順序進行存取的儲存區,操作順序分為“後進先出”和“先進後出”
堆疊定址時隱含的,它使用一個專門的暫存器(堆疊指標)指向一塊儲存區域(堆疊),
指標所指向的儲存單元就是堆疊的棧頂。儲存器堆疊可分為兩種:
向上生長:向高地址方向生長,稱為遞增堆疊
向下生長:向低地址方向生長,稱為遞減堆疊
堆疊指標指向最後壓入的堆疊的有效資料項,
稱為滿堆疊;
堆疊指標指向下一個要
放入的空位置,
稱為空堆疊。
這樣就有 4 中型別的堆疊表示遞增和遞減的滿堆疊和空堆疊的各種組合。

  1. 滿遞增:堆疊通過增大儲存器的地址向上增長,堆疊指標指向內含有效資料項的最高地址。
    指令如 LDMFA,STMFA 等。
  2. 空遞增:堆疊通過增大儲存器的地址向上增長,堆疊指標指向堆疊上的第一個空位置。
    指令如 LDMEA,STMEA 等。
  3. 滿遞減:
    堆疊通過減小儲存器的地址向下增長,堆疊指標指向內含有效資料項的最低地址。
    指令如 LDMFD,STMFD 等。
  4. 空遞減:堆疊通過減小儲存器的地址向下增長,堆疊指標指向堆疊下的第一個空位置。
    指令如 LDMED,STMED 等。
    堆疊定址指令舉例如下:
    STMFD SP!,{R1-R7,LR} ; 將 R1~R7,LR 入棧。滿遞減堆疊。
    LDMFD SP!,{R1-R7,LR} ;資料出棧,放入 R1~R7,LR 暫存器。滿遞減堆疊。

彙編跳轉指令B、BL、BX、BLX 和 BXJ

本文摘錄於:https://blog.csdn.net/bytxl/article/details/49883103
跳轉指令用於實現程式流程的跳轉,在 ARM 程式中有兩種方法可以實現程式流程的跳轉:
(1) 使用專門的跳轉指令。
(2) 直接向程式計數器 PC 寫入跳轉地址值。
通過向程式計數器 PC 寫入跳轉地址值,可以實現在 4GB 的地址空間中的任意跳轉,在跳轉之前結合使用
MOV LR , PC
等類似指令,可以儲存下一條指令地址作為將來的返回地址值,從而實現在 4GB 連續的線性地址空間的子程式呼叫。
專門的跳轉指令
B、BL、BX、BLX 和 BXJ:
跳轉、帶連結跳轉(帶返回的跳轉)、跳轉並切換指令集、帶連結跳轉並切換指令集(帶返回的跳轉並切換指令集)、跳轉並轉換到 Jazelle 狀態。
1、 B 指令
B 指令的格式為:
B{條件} 目標地址
B 指令是最簡單的跳轉指令。一旦遇到一個 B 指令,ARM 處理器將立即跳轉到給定的目標地址,從那裡繼續執行。注意:B指令是不會把當前指標存放到R14暫存器的,注意儲存在跳轉指令中的實際值是相對當前PC 值的一個偏移量,而不是一個絕對地址,它的值由彙編器來計算(參考定址方式中的相對定址)。它是 24 位有符號數,左移兩位後有符號擴充套件為 32 位,表示的有效偏移為 26 位(前後32MB 的地址空間)。以下指令:
B Label ;程式無條件跳轉到標號 Label 處執行
CMP R1 ,# 0 ;當 CPSR 暫存器中的 Z 條件碼置位時,程式跳轉到標號 Label 處執行
BEQ Label
2、 BL 指令
BL 指令的格式為:
BL{條件} 目標地址
BL 是另一個跳轉指令,但跳轉之前,會在暫存器R14 中儲存PC 的當前內容,因此,可以通過將R14 的內容重新載入到PC 中,來返回到跳轉指令之後的那個指令處執行。該指令是實現子程式呼叫的一個基本但常用的手段。以下指令:
BL Label ;當程式無條件跳轉到標號 Label 處執行時,同時將當前的 PC 值儲存到 R14 中
3、 BLX 指令
BLX 指令的格式為:
BLX 目標地址
BLX 指令從ARM 指令集跳轉到指令中所指定的目標地址,並將處理器的工作狀態有ARM 狀態切換到Thumb 狀態,該指令同時將PC 的當前內容儲存到暫存器R14 中。因此,當子程式使用Thumb 指令集,而呼叫者使用ARM 指令集時,可以通過BLX 指令實現子程式的呼叫和處理器工作狀態的切換。
同時,子程式的返回可以通過將暫存器R14 值複製到PC 中來完成。
4、 BX 指令
BX 指令的格式為:
BX{條件} 目標地址
BX 指令跳轉到指令中所指定的目標地址,目標地址處的指令既可以是ARM 指令,也可以是Thumb指令。
總結
語法
op1{cond}{.W} label<wbr>

op2{cond} Rm
其中:
op1
是下列項之一:
B
跳轉。
BL
帶連結跳轉
BLX
帶連結跳轉並切換指令集。
op2
是下列項之一:
BX
跳轉並切換指令集。
BLX
帶連結跳轉並切換指令集。
BXJ
跳轉並轉換為 Jazelle 執行。
cond
是一個可選的條件程式碼。 cond 不能用於此指令的所有形式。
.W
是一個可選的指令寬度說明符,用於強制要求在 Thumb-2 中使用 32 位 B 指令。
label
是一個程式相對的表示式。
Rm
是一個暫存器,包含要跳轉到的目標地址。
操作
所有這些指令均會引發跳轉,或跳轉到 label,或跳轉到包含在 Rm 中的地址處。 此外:
BL 和 BLX 指令可將下一個指令的地址複製到 lr(r14,連結暫存器)中。
BX 和 BLX 指令可將處理器的狀態從 ARM 更改為 Thumb,或從 Thumb 更改為 ARM。
BLX label 無論何種情況,始終會更改處理器的狀態。
BX Rm 和 BLX Rm 可從 Rm 的位 [0] 推算出目標狀態:
如果 Rm 的位 [0] 為 0,則處理器的狀態會更改為(或保持在)ARM 狀態
如果 Rm 的位 [0] 為 1,則處理器的狀態會更改為(或保持在)Thumb 狀態。
BXJ 指令會將處理器的狀態更改為 Jazelle
http://www.techbulo.com/535.html
http://luleimi.blog.163.com/blog/static/175219645201210922139272/<wbr>

**

ARM的六大類指令集—LDR、LDRB、LDRH、STR、STRB、STRH

**
本文摘錄於:https://blog.csdn.net/u013477200/article/details/50723555

ARM微處理器支援載入/儲存指令用於在暫存器和儲存器之間傳送資料,載入指令用於將儲存器中的資料傳送到暫存器,儲存指令則完成相反的操作。常用的載入儲存指令如下:

— LDR 字資料載入指令

— LDRB 位元組資料載入指令

— LDRH 半字資料載入指令

— STR 字資料儲存指令

— STRB 位元組資料儲存指令

— STRH 半字資料儲存指令
1、LDR指令

LDR指令的格式為:

LDR{條件} 目的暫存器,<儲存器地址>

LDR指令用於從儲存器中將一個32位的字資料傳送到目的暫存器中。該指令通常用於從儲存器中讀取32位的字資料到通用暫存器,然後對資料進行處理。當程式計數器PC作為目的暫存器時,指令從儲存器中讀取的字資料被當作目的地址,從而可以實現程式流程的跳轉。該指令在程式設計中比較常用,且定址方式靈活多樣,請讀者認真掌握。

指令示例:

LDR R0,[R1] ;將儲存器地址為R1的字資料讀入暫存器R0。

LDR R0,[R1,R2] ;將儲存器地址為R1+R2的字資料讀入暫存器R0。

LDR R0,[R1,#8] ;將儲存器地址為R1+8的字資料讀入暫存器R0。

LDR R0,[R1,R2] ! ;將儲存器地址為R1+R2的字資料讀入暫存器R0,並將新地址R1+R2寫入R1。

LDR R0,[R1,#8] ! ;將儲存器地址為R1+8的字資料讀入暫存器R0,並將新地址R1+8寫入R1。

LDR R0,[R1],R2 ;將儲存器地址為R1的字資料讀入暫存器R0,並將新地址R1+R2寫入R1。

LDR R0,[R1,R2,LSL#2]! ;將儲存器地址為R1+R2×4的字資料讀入暫存器R0,並將新地址R1+R2×4寫入R1。

LDR R0,[R1],R2,LSL#2 ;將儲存器地址為R1的字資料讀入暫存器R0,並將新地址R1+R2×4寫入R1。
2、LDRB指令

LDRB指令的格式為:

LDR{條件}B 目的暫存器,<儲存器地址>

LDRB指令用於從儲存器中將一個8位的位元組資料傳送到目的暫存器中,同時將暫存器的高24位清零。該指令通常用於從儲存器中讀取8位的位元組資料到通用暫存器,然後對資料進行處理。當程式計數器PC作為目的暫存器時,指令從儲存器中讀取的字資料被當作目的地址,從而可以實現程式流程的跳轉。

指令示例:

LDRB R0,[R1] ;將儲存器地址為R1的位元組資料讀入暫存器R0,並將R0的高24位清零。

LDRB R0,[R1,#8] ;將儲存器地址為R1+8的位元組資料讀入暫存器R0,並將R0的高24位清零。
3、LDRH指令

LDRH指令的格式為:

LDR{條件}H 目的暫存器,<儲存器地址>

LDRH指令用於從儲存器中將一個16位的半字資料傳送到目的暫存器中,同時將暫存器的高16位清零。該指令通常用於從儲存器中讀取16位的半字資料到通用暫存器,然後對資料進行處理。當程式計數器PC作為目的暫存器時,指令從儲存器中讀取的字資料被當作目的地址,從而可以實現程式流程的跳轉。

指令示例:

LDRH R0,[R1] ;將儲存器地址為R1的半字資料讀入暫存器R0,並將R0的高16位清零。

LDRH R0,[R1,#8] ;將儲存器地址為R1+8的半字資料讀入暫存器R0,並將R0的高16位清零。

LDRH R0,[R1,R2] ;將儲存器地址為R1+R2的半字資料讀入暫存器R0,並將R0的高16位清零。

4、LDM指令:

L的含義仍然是LOAD,即是Load from memory into register。

雖然貌似是LDR的升級,但是,千萬要注意,這個指令執行的方向和LDR是不一樣的,是從左到右執行的。該指令是將記憶體中堆疊內的資料,批量的賦值給暫存器,即是出棧操作;其中堆疊指標一般對應於SP,注意SP是暫存器R13,實際用到的卻是R13中的記憶體地址,只是該指令沒有寫為[R13],同時,LDM指令中暫存器和記憶體地址的位置相對於前面兩條指令改變了,下面的例子:

LDMFD SP! , {R0, R1, R2}

實際上可以理解為: LDMFD [SP]!, {R0, R1, R2}

意思為:把sp指向的3個連續地址段(應該是3*4=12位元組(因為為r0,r1,r2都是32位))中的資料拷貝到r0,r1,r2這3個暫存器中去。

5、STR指令

STR指令的格式為:

STR{條件} 源暫存器,<儲存器地址>

STR指令用於從源暫存器中將一個32位的字資料傳送到儲存器中。該指令在程式設計中比較常用,且定址方式靈活多樣,使用方式可參考指令LDR。

指令示例:

STR R0,[R1],#8 ;將R0中的字資料寫入以R1為地址的儲存器中,並將新地址R1+8寫入R1。

STR R0,[R1,#8] ;將R0中的字資料寫入以R1+8為地址的儲存器中。
6、STRB指令

STRB指令的格式為:

STR{條件}B 源暫存器,<儲存器地址>

STRB指令用於從源暫存器中將一個8位的位元組資料傳送到儲存器中。該位元組資料為源暫存器中的低8位。

指令示例:

STRB R0,[R1] ;將暫存器R0中的位元組資料寫入以R1為地址的儲存器中。

STRB R0,[R1,#8] ;將暫存器R0中的位元組資料寫入以R1+8為地址的儲存器中。
7、STRH指令

STRH指令的格式為:

STR{條件}H 源暫存器,<儲存器地址>

STRH指令用於從源暫存器中將一個16位的半字資料傳送到儲存器中。該半字資料為源暫存器中的低16位。

指令示例:

STRH R0,[R1] ;將暫存器R0中的半字資料寫入以R1為地址的儲存器中。

STRH R0,[R1,#8] ;將暫存器R0中的半字資料寫入以R1+8為地址的儲存器中。

8、STM指令:

S的含義仍然是STORE,與LDM是配對使用的,其指令格式上也相似,即區別於STR,是將堆疊指標寫在左邊,而把暫存器組寫在右邊。

STMFD SP!, {R0}

同樣的,該指令也可理解為: STMFD [SP]!, {R0}

意思是:把R0儲存到堆疊(sp指向的地址)中。


本文來自 BOOK0614 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/u013477200/article/details/50723555?utm_source=copy

**

ARM彙編指令LSL/LSR/ASL/ASR

**
本文摘錄於:http://www.eeworld.com.cn/mcu/2015/0930/article_22693.html
移位
LSL
ASL
LSR
ASR
ROR
RRX
ARM 處理器組建了可以與資料處理指令(ADC、ADD、AND、BIC、CMN、CMP、EOR、MOV、MVN、ORR、RSB、SBC、SUB、TEQ、TST)一起使用的桶式移位器(barrel shifter)。你還可以使用桶式移位器影響在 LDR/STR 操作中的變址值。
譯註:移位操作在 ARM 指令集中不作為單獨的指令使用,它是指令格式中是一個欄位,在組合語言中表示為指令中的選項。如果資料處理指令的第二個運算元或者單一資料傳送指令中的變址是暫存器,則可以對它進行各種移位操作。如果資料處理指令的第二個運算元是立即值,在指令中用 8 位立即值和 4 位迴圈移位來表示它,所以對大於 255 的立即值,彙編器嘗試通過在指令中設定迴圈移位數量來表示它,如果不能表示則生成一個錯誤。在邏輯類指令中,邏輯運算指令由指令中 S 位的設定或清除來確定是否影響進位標誌,而比較指令的 S 位總是設定的。在單一資料傳送指令中指定移位的數量只能用立即值而不能用暫存器。
下面是給不同的移位型別的六個助記符:
LSL 邏輯左移 ASL 算術左移 LSR 邏輯右移 ASR 算術右移 ROR 迴圈右移 RRX 帶擴充套件的迴圈右移
ASL 和 LSL 是等同的,可以自由互換。
你可以用一個立即值(從 0 到 31)指定移位數量,或用包含在 0 和 31 之間的一個值的暫存器指定移位數量。

邏輯或算術左移
(Logical or Arithmetic Shift Left)
Rx, LSL #n or Rx, ASL #n or Rx, LSL Rn or Rx, ASL Rn
接受 Rx 的內容並按用‘n’或在暫存器 Rn 中指定的數量向高有效位方向移位。最低有效位用零來填充。除了概念上的第 33 位(就是被移出的最小的那位)之外丟棄移出最左端的高位,如果邏輯類指令中 S 位被設定了,則此位將成為從桶式移位器退出時進位標誌的值。
考慮下列:
MOV R1, #12 MOV R0, R1, LSL#2
在退出時,R0 是 48。 這些指令形成的總和是 R0 = #12, LSL#2 等同於 BASIC 的 R0 = 12 << 2

邏輯右移
(Logical Shift Right)
Rx, LSR #n or Rx, LSR Rn
它在概念上與左移相對。把所有位向更低有效位方向移動。如果邏輯類指令中 S 位被設定了,則把最後被移出最右端的那位放置到進位標誌中。它同於 BASIC 的 register = value >>> shift。

算術右移
(Arithmetic Shift Right)
Rx, ASR #n or Rx, ASR Rn
類似於 LSR,但使用要被移位的暫存器(Rx)的第 31 位的值來填充高位,用來保護補碼錶示中的符號。如果邏輯類指令中 S 位被設定了,則把最後被移出最右端的那位放置到進位標誌中。它同於 BASIC 的 register = value >> shift。

迴圈右移
(Rotate Right)
Rx, ROR #n or Rx, ROR Rn
迴圈右移類似於邏輯右移,但是把從右側移出去的位放置到左側,如果邏輯類指令中 S 位被設定了,則同時放置到進位標誌中,這就是位的‘迴圈’。一個移位量為 32 的操作將導致輸出與輸入完全一致,因為所有位都被移位了 32 個位置,又回到了開始時的位置!

帶擴充套件的迴圈右移
(Rotate Right with extend)
Rx, RRX
這是一個 ROR#0 操作,它向右移動一個位置 - 不同之處是,它使用處理器的進位標誌來提供一個要被移位的 33 位的數量。

相關文章