一. Load/Store 指令
1. 前變址
前變址指令是在讀取或存儲數據時,先根據基址寄存器(Rn)與偏移量(offset)計算出有效地址,再進行數據操作。相關指令及示例如下:
-
LDR R0, [R1, #4]
:從地址R1 + 4
處讀取一個字(32 位)到R0
。假設R1 = 0x10000000
,指令執行后R0 = 0x88776655
,R1
的值保持為0x10000000
?。 -
LDRB R2, [R1, #4]
:從地址R1 + 4
處讀取一個字節(8 位)到R2
,高位補零擴展為 32 位。執行后R2 = 0x00000055
,R1
的值不變。 -
LDRH R3, [R1, #4]
:從地址R1 + 4
處讀取一個半字(16 位)到R3
,高位補零擴展為 32 位。執行后R3 = 0x00006655
,R1
的值不變。 -
LDRSB R4, [R1, #7]
:從地址R1 + 7
處讀取一個字節,執行符號擴展成 32 位后存入R4
。執行后R4 = 0xFFFFFFFF88
,R1
的值不變。
前變址指令詳細說明如下:
指令 | 功能描述 |
---|---|
| 從地址 |
| 從地址 |
| 從地址 |
| 從地址 |
| 把 |
| 把 |
| 把 |
| 把 |
| 字節 / 半字的自動變址加載,并且在加載后執行符號擴展成 32 位 |
2.自動變址
自動變址指令在完成數據操作后,會自動對基址寄存器進行調整。
以? ?LDR.W R0, [R1, #20]!??
為例,執行步驟如下:
-
先計算
R1 = R1 + 20
?。 -
然后將計算后的地址
R1
中的數據讀取到R0
?。
自動變址指令詳細說明如下:
指令 | 功能描述 |
---|---|
| 字 / 字節 / 半字 / 雙字的自動變址加載(不做帶符號擴展,沒有用到的高位全部置 0) |
| 字節 / 半字的自動變址加載,并且在加載后執行符號擴展成 32 位整數 |
| 字 / 字節 / 半字 / 雙字的自動變址存儲 |
3.后變址
后變址指令先以基址寄存器(Rn)的當前值進行數據操作,然后再對基址寄存器進行調整。
以STR.W R0, [R1], #-12
為例,執行步驟如下:
-
先將
R0
的數據存儲到地址R1
處。 -
然后計算
R1 = R1 + (-12)
?。
后變址指令詳細說明如下:
指令 | 功能描述 |
---|---|
| 字 / 字節 / 半字 / 雙字的帶后索引加載(不做帶符號擴展,沒有用到的高位全清 0) |
| 字節 / 半字的帶后索引加載,并且在加載后執行符號擴展成 32 位整數 |
| 字 / 字節 / 半字 / 雙字的帶后索引存儲 |
后變址應用舉例:
-
LDR R0, [R1], #4
:假設R1 = 0x10000000
,先從地址R1
(即0x10000000
)處讀取一個字到R0
,R0 = 0x44332211
,然后R1 = R1 + 4 = 0x10000004
?。 -
LDRB R2, [R1], #4
:從地址R1
(此時R1 = 0x10000004
)處讀取一個字節到R2
,R2 = 0x00000011
,接著R1 = R1 + 4 = 0x10000004
?。 -
LDRH R3, [R1], #4
:從地址R1
(0x10000004
)處讀取一個半字到R3
,R3 = 0x00002211
,之后R1 = R1 + 4 = 0x10000004
?。 -
LDRSB R4, [R1], #7
:從地址R1
(0x10000004
)處讀取一個字節并符號擴展到 32 位存入R4
,R4 = 0x00000011
,最后R1 = R1 + 7 = 0x10000007
?。
Load/Store 指令綜合舉例(字序調整):
假設內存地址0x1000
處存儲的值為0x12345678ABCDEF00
,執行以下指令:
-
LDR R2, =0x1000
:將地址0x1000
加載到R2
?。 -
LDRD.W R0, R1, [R2]
:從地址R2
(即0x1000
)處讀取一個雙字,R0 = 0xABCDEF00
,R1 = 0x12345678
?。 -
STRD.W R1, R0, [R2]
:把R1
(低 32 位)和R0
(高 32 位)存儲到地址R2
(0x1000
)處,此時(0x1000) = 0xABCDEF0012345678
?。
二. 批量數據傳送指令
1.?批量數據 Load/Store 指令
這些指令用于在內存與多個寄存器之間批量傳輸數據,Rd
后面的!
表示在每次訪問前(Before)或訪問后(After),要自增(Increment)或自減(Decrement)基址寄存器Rd
的值,增 / 減單位為 1 個字(4 字節)。具體指令如下:
指令 | 功能描述 |
---|---|
| 從 |
| 存儲多個字到 |
| 從 |
| 從 |
| 存儲多個字到 |
| 存儲多個字到 |
例如,當R8 = 0x8000
時:
-
STMIA.W R8!, {R0 - R3}
:每存儲一次,R8
的值增加 4 字節,先存儲R0 - R3
的值,然后R8
自增。執行后R8
值變為0x8010
?。 -
STMDB.W R8!, {R0 - R3}
:每存儲一次,R8
的值減少 4 字節,先自減R8
,然后存儲R0 - R3
的值。執行后R8
值變為0x7FF0
?。
2.堆棧傳送類指令
-
STMDB SP!, [R0 - R3, LR]
:等效于PUSH {R0 - R3, LR}
,將寄存器R0 - R3
和鏈接寄存器LR
的值壓入堆棧,堆棧指針SP
在存儲前遞減。 -
LDMIIA SP!, {R0 - R3, PC}
:等效于POP {R0 - R3, PC}
,從堆棧中彈出數據到寄存器R0 - R3
和程序計數器PC
,堆棧指針SP
在讀取后遞增。