# 組合語言
## CH1 An Overview of Computing Systems 計算系統概述
### 問題
#### What is an assembler?
把彙編語言書寫的程式翻譯成與之等價的機器語言程式的翻譯程式。 彙編程式輸入的是用彙編語言書寫的源程式,輸出的是用機器語言表示的目標程式。
#### What hardware and software are needed?
Editor, Assembler, Linker, Debugger(編譯器、彙編程式、連結器、偵錯工具)
#### What does assembly language related to machine language?
組合語言程式指令與機器語言指令呈一對一的關係;但組合語言所寫的程式,機器無法接受,因此必須透過系統所提供的組合程式加以組譯,才能為機器所接受並加以執行。
#### Is assembly language portable(移植)?
組合語言對應著不同的機器語言指令集。 一種組合語言專用於某種電腦系統結構
#### Why learn assembly language?
* Write ==embedded system programs(嵌入式系統程式)==
* To be ==highly optimized(高度最佳化)== for both space and run time speed
* Overall understanding of interaction between the computer hardware, ==operating system(作業系統)==, and application programs
* Break through the ==limitations(限制)== of high level languages in certain types of operations
* Create ==device drivers(設備驅動程式)== for the equipment
### 語言易讀性

由高到低:高階語言、組合語言、作業系統、指令集架構、微架構、數位邏輯
ex:
English: Display the sum of A times B plus C.
C++: cout<<(A * B + C);
Assembly Language: MOV EAX,A
MUL B
ADD EAX,C
CALL WriteInt
Intel Machine Language:
A1 00000000
F7 25 00000004
03 05 00000008
E8 00500000
### 基本運算系統

### ARM 架構
* 32-bit RISC-processor core (32-bit instructions)32 位元 RISC 處理器核心(32 位元指令)
* 37 pieces of 32-bit integer registers (16 available)37個32位元整數暫存器(16個可用)
### ARM instruction set指令集(六大類指令)
* ==Load載入== and ==store儲存== instructions(==data transfer資料傳輸==)
* ==Data processing資料處理== instructions(==arithmetic and logic算術和邏輯==)
* ==Branch分支== instructions(control flow)
* ==Status register狀態暫存器== ==transfer傳輸== instructions(flag operations)
* ==Exception-generating異常產生== instructions(SWI & BKPT)
* ==Coprocessor協同處理器== instructions
## CH2 Programmer’s Model
存資料的地方:**Memory/Memory map、Registers**
<font color="#00f">Memory/Memory map:記憶體映射技術是將系統上裝置兩組記憶體,透過映射動作產生兩組資料完全相同的記憶體,等於有了個完全一模一樣的備份記憶體系統。當其中一組記憶體損壞時,便可利用記憶體熱抽換技術更換記憶體,系統將可維持不中斷,完全不影響企業正常作業,確保資料儲存的安全性。</font>
What happens when you give the machine an ==invalid instruction無效指令==?
**Operational flags: Status and Control flags操作標誌:狀態和控制標誌**
==Exceptions(例外): Processor modes處理器模式==
### Data types
* Byte (8-bit)
* Halfword (16-bit):讀/寫必須與兩位元組邊界==對齊aligned==
* Word (32-bit):字元必須與四位元組邊界==對齊aligned==
### Endianness位元組順序
**Little-endian aligning小端對齊**
<font color="#00f">A byte(halfword) at a word-aligned address is the least significant byte(halfword) within the word at that address字對齊位址處的位元組是該位址處字內的最低有效位元組</font>
**Big-endian aligning大端對齊**
<font color="#00f">A byte(halfword) at a word-aligned address is the most significant byte(halfword) within the word at that address字對齊位址處的位元組是該位址處字內的最高有效位元組</font>
### Processor modes處理器模式
* **USER(usr)用戶模式**: Normal program execution執行 state
* 大多數應用程式將在 USER 模式下執行
* 正在執行的程式無法存取某些受保護的系統資源或變更模式
* **FIQ(fiq)快速中斷模式**: Data transfer state (fast irq, DMA-type transfer)用於高速數據傳輸或通道處理。
* **IRQ(irq)外部中斷模式**: Used for ==general interrupt services一般中斷服務==
* **SUPERVISOR(svc)管理模式**: Protected mode for operating system support
* **ABORT(abt)數據訪問中止模式**: Selected when data or instruction fetch is aborted當資料或指示取得被中止時選擇
* **SYSTEM(sys)系統模式**: Operating system ==‘privilege特權’==-mode for user
* privilege mode特權模式
* have full access to system resources
* Can change mode freely
* Each of them has a ==service routine服務例程== (in operating systems)
* Each of them has some additional registers to avoid corrupting User mode state
* **UNDEFINIED(und)未定義指令中止模式**: Selected when undefined instruction is fetched
### ARM register暫存器
ARM 總共有 37 個暫存器
**general-purpose registers通用暫存器:31個**
* The unbanked registers通用暫存器: R0 ~ R7
* The banked registers分組暫存器: R8 ~ R14
* r13 : 堆疊暫存器(SP/Stack Pointer) : 指向目前處理器模式的堆疊的堆疊頂端
* 14 : 連結暫存器 (LR/Link Register) : 存放(副)函數返回的位置,可在==exception occurs異常發生==時自動儲存返回地址
* Register 15程式計數器, the (PC/ Program Counter) : 儲存、指向下一道要執行的指令的位置
* There are many ==instruction-specific restrictions特定指令限制== or special cases about its use
* The ==instruction指令== is ==UNPREDICTABLE不可預測== if R15 is used in a manner that breaks these ==restrictions限制==
**Program status registers狀態暫存器:6個**
* CPSR: ==Current Program Status Register目前程式狀態暫存器==:儲存 “flag bits”(條件旗標)、中斷位元、紀錄Arm模式…
* SPSR: ==Saved Program Status Register儲存程式狀態暫存器==:當異常出現時,用來儲存 CPSR 值,以便異常處理結束後返璇工作狀態
### Flags

* Condition code flags: N, Z, C, V
* N : Negative
If this result is regarded as a two's complement signed integer, then N = 1 if the result is negative and N = 0 if it is positive or zeroN=1 結果為負數N=0 結果為正數 or 零
* Z : Zero
Is set to 1 if the result of the instruction is zero (which often indicates an equal result from a comparison), and to 0 otherwise.
* C : Carry
* ==C is set to 1== if the ==addition produced a carry加法產生進位== (that is, an unsigned overflow), and to 0 otherwise.
* ==C is set to 0== if the ==subtraction produced a borrow減法產生借位== (that is, an unsigned underflow), and to 1 otherwise
* For non-addition/subtractions that incorporate a shift operation, C is set to the last bit shifted out of the value by the shifter.對於包含移位操作的非加法/減法,C 被設定為移位器移出值的最後一位。
* For other non-addition/subtractions, ==C is normally left unchanged(C不變)==
* V: oVerflow
For an ==addition加法== or ==subtraction減法==, V is set to 1 if signed overflow occurred, regarding the operands and result as two's complement signed integers
* Control bits: I, F, T
The control bits change when an ==exception異常== arises and can be altered by software only when the processor is in a ==privileged mode==
* Mode bits: M4, M3, M2, M1, M0
### Address space
* Directly直接 access address space—flat (physical) address space
* Addressing lines尋址行 : n-bit
* Addressing space尋址空間 = 2n bytes
* Memory space allocation分配
* ==Dedicated (reserved)專用(保留)== memory space
* Free (User) space
* Memory-mapped I/O space
#### Exception例外(異常)
* Exceptions are generated by ==internal and external sources內部和外部來源== to cause the processor to handle an event, e.g., ==an externally generated interrupt外部生成的中斷== or an ==attempt to execute執行 an undefined instruction.==
* The processor state just before handling the exception must be preserved保留 so that the original program can be resumed恢復
* More than one exception can arise at the same time
#### Reset重置
* When the Reset input is asserted輸入 on the processor, the ARM processor immediately立即 stops execution of the current instruction
* After Reset, the ARM processor ==begins execution at address 0x00000000 or 0xFFFF0000== in Supervisor mode with ==interrupts disabled停用中斷==
## CH3 Tutorial: First Programs
### Instructions指令
* **==Pseudo instruction偽指令==** (Directive instruction)
* An element元素 in an assembly language that is similar to an instruction but ==provides control information== to the assembler ==as opposed不是== to ==generating a particular instruction==
* Not part of the Intel instruction set
* Used to ==declare code聲明程式碼==, ==data areas資料區==, ==select memory model選擇記憶體模型==, ==declare procedures聲明流程==, etc.
* **Executable instructions可執行指令**(machine instructions)
* Executed at runtime by the CPU
#### An assembly instruction statement contains包含 four fields
* Label標籤 (optional)
* Act as place markers地點標記
* marks the address (offset) of code and data
* Follow **identifier標識碼** rules
* Data label
* **must be unique: example: myArray**
* Code label
* target of jump and loop instructions
* Mnemonic助記詞 (required)

* Operand操作數 (depends on the instruction)
* Constant or constant expression常量或常量表達式
* Constants and constant expressions are often called immediate values即時值
* Register
* Memory (data label)
* Comment註解 (optional)
* Begin with semicolon (;)
* Explain the program's purpose目的
* When it was written, and by whom
* Revision information修訂資訊
* Tricky coding techniques棘手的編碼技術
* Application-specific explanations特定於應用程式的說明
### Program 1: Shifting data 平移資料
```AREA Prog1, CODE, READONLY
ENTRY
MOV R0, #0X11 ; Load initial value
MOV R1, R0, LSL #1 ; Shift 1 bit left
MOV R2, R1, LSL #1 ; Shift 1 bit left
STOP B STOP ; Stop program
END
```
instruction destination, source, source
MOV : 移動
MOV R0, #0X11 : 將11值移動到位置R0
MOV R1, R0, LSL #1: 將整個r0向左平移1格後的值給給R1
### Program 2: Factorial calculation階乘
```AREA Prog2, CODE, READONLY
ENTRY
MOV R6, #10 ; Load 10 into R6
MOV R4, R6 ; Copy n into a temp register
LOOP SUBS R4, R4, #1 ; Decrement next multiplier
MULNE R7, R6, R4 ; Perform multiply
MOV R6, R7
BNE LOOP ; Go again if not complete
STOP B STOP ; Stop program
END
```
LOOP : 迴圈
SUBS : 減法
=> SUBS R4, R4, #1 =>將R4值減1後放入R4中
MULNE : 乘法 => 將R6與R4值相乘後放入R7
BNE LOOP : 若R4、R6、R7皆不為0 => 繼續迴圈
### 基本指令

巨集指令:用一整個小程式作為一個指令
嵌入式系統:Embedded Systems
*ALIGN=>對其,在拿取資料的時候可以一次拿?
ex: ALIGN 4,3=> 儲存空間以四個為一組,放在的三個位置(位置從0開始數)
*SPACE:預留塊記憶空間
*LTORG:用來支持ON裡面的指令(不常用)
## CH4 Assembler Rules and Directives 組合器規則和指令
### Structure of assembly language modules組合語言模組的結構
```
AREA ARMex, CODE, READONLY
; Name this block of code ARMex
將此程式碼區塊命名為 ARMex
ENTRY ; Mark first instruction to execute
標記要執行的第一條指令
... ; Executable or pseudo instructions
可執行或偽指令
END ; Mark end of code ARMex
標記程式碼結束 ARMex
```
### 指令格式
```
label instruction或directive或pseudo-instruction ;comment
```
==label標籤== ==instruction指令或directive指令或pseudo-instruction偽指令== ==;comment註解==
* **指令**不能從第一列開始(若前面沒有符號,須以空格開頭)
#### Label
* To represent ++variables變數++, ++addresses位址++, and ++numeric constants數值常數++
* Must begin in the ++first column第一列++
* Character-set: {uppercase/lowercase letters, numeric characters, or the underscore character}
字元集:{大寫/小寫字母、數字字元或底線字元}
* Do **not** use ==numeric characters數字字符== for the first character of symbol names, **except in local labels**
* Symbol符號 names are **case-sensitive區分大小寫**
* 符號中每個字元都很重要
* 須確保此名稱在使用範圍內為唯一的
* Symbols must **not use** ==built-in variable names內置變數名稱== or ==predefined symbol names預定義的符號名稱==
* Symbols must not use the same name as ==instruction mnemonics指令助記符== or ==directives與指令相同的名稱==
e.g., <font color="#f00"> START_AT, LOOP_FOR, …</font>
:::info
在組合語言中要實現流程控制時,往往需要讓程式計數器前移或後移一段距離(例如前移5個位元),移動的距離會因程式碼變動而不同,例如在某處增加(或刪除)一行程式碼,程式中所有有越過更改程式碼的前移(及後移)指令都要重新計算需移動的距離。這樣的程式在閱讀時需經過計算才能知道任何跳躍指令的終點,程式的可讀性顯然不佳。
標記可以避免上述的問題。可以在程式任何需要的位置加上不同標記,跳躍指令直接指定其終點對應的標記,不需用人工計算程式計數器移動的距離。而且還可以使用有意義,可讀性高的標記,更加提昇程式的可讀性。
:::
以下是一段使用標記的組合語言程式:
```AREA Prog1, CODE, READONLY
mov $v0, 0
MyLabel: ; 此處為一個名稱為MyLabel的標記
add $v0, $s0 ; 迴圈本體中的程式
subi $t0, 1 ; 迴圈本體中的程式
bne $t0, $zero, MyLabel ; 條件跳躍至MyLabel標記處
; 若指定條件不滿足,繼續執行後續的程式
```
#### Instruction/directive/pseudo-instruction field 指令/指令/偽指令字段
Must be preceded by a white space前面必須有一個空格
指令集

#### Comment field 註記
* 註記難以理解部分
* The first semicolon分號 on a line indicates表示 the beginning of a comment—==unless in the string constant; e.g., “string ;”除非在字串常數中; 例如,“字串;”==
#### 組語常用常量
* Numeric constants
* Decimal十進制 : 123
* Hexadecimal十六進制 : 0x3F
* n進制:n_XXX => n表示2~9,XXX表示實際值
ex:5_4214 => 五進制,4214為實際值
Predefined register預先定義的暫存器 names:要區分大小寫
#### 預先聲明的暫存器(r0~r15):
|register暫存器 | 名稱 |
| -------- | -------- |
| r0~r3 |a1-a4(argument參數, result結果, or scratch registers暫存暫存器) |
|r4~r11 | variable registers變數暫存器(v1~v8) |
|r9 | static base靜態基地(sb and SB)|
|r10 |stack limit堆疊限制(sl and SL)|
|r11 |frame pointer影格指標(fp and FP )|
|r12 |intra-procedure-call scratch register過程內呼叫暫存暫存器(ip and IP )|
|r13 |stack pointer堆疊指標(sp and SP )|
|r14 |link register連結暫存器(lr and LR )|
|r15 |program counter程式計數器(pc and PC )|
#### Frequently used directives指令
| Directive | Comment|
| -------- | -------- |
| AREA | Defines a block區塊 of data or code |
| RN | Equates等於 a register with name|
| EQU | Equates a label to a numeric constant|
| ENTRY |Declares an entry point to your program|
| DCB | Allocate one or more bytes of memory. It also specifies the initial runtime contents of memory 分配一個或多個位元組的記憶體。 它還指定記憶體的初始運行時內容|
| DCW |Allocate one or more halfwords of memory including initial run time contents 分配一個或多個半字內存,包括初始運行時內容 |
| DCD | Allocate one or more words of memory including initial run time contents分配一個或多個記憶體字,包括初始運行時內容|
| ALIGN | Aligns data or code to a particular memory boundary 將數據或代碼與特定記憶體邊界對齊|
| SPACE |Reserves a zeroed block of memory of a particular size 保留特定大小的歸零記憶體區塊|
| LTORG | Assigns the string point of a literal pool分配文字池的字串點|
| END | Designates the end of a source file指定原始檔的結尾|
* **AREA**
* The AREA directive instructs the assembler to assemble a new code or data sectionAREA 偽指令指示彙編器彙編新的程式碼或資料部分
* Sections節 are independent獨立的, named命名的, ==indivisible chunks不可分割的== of code or data that are manipulated by the linker連結器
* Syntax語法:
* Namesstarting with a digit數位 must be enclosed in bars小節; e.g., ==|123_Digital|==
* **attr** are one or more comma-delimited以逗號分隔 section部分 attributes屬性
* **CODE** : Contains machine instructions. ==READONLY== is the default預設值
* **DATA** : Contains包含 data, not instructions指令. READWRITE is the default
* **READONLY**:表示此部分不應寫入這是代碼區域的預設值
* **READWRITE**:表示此部分可以讀取和寫入這是數據區域的預設值
* 使用 AREA 指令將==源檔source file==細分為多個部分
* 大型程式通常可以方便地分為幾個程式碼段
* 範例:
```AREA Prog1, CODE, READONLY
AREA Example, CODE, READONLY ; an example code section示例代碼節
```
* RN
* RN 指令定義指定暫存器的寄存器名稱
* 語法:
* where
* **name** : 分配給暫存器的名字,不可與處理器中任何預設值得名稱相同
* **expr** :暫存器編號
* 範例:
```AREA Prog1, CODE, READONLY
coeff1 RN 8 ; r8 = coeff1
coeff2 RN 9 ; r9 = coeff2
dest RN 0 ; r0 = dest
```
* **EQU**
* 為數值常量、暫存器相對值或程序相對值提供符號名稱
* EQU 的同義詞 : ==*==
* 類似於在 C 中使用 #define 定義常量
* 實際上不會在特定的記憶體位置放置任何內容
* 語法:
* **name**:分配給值的符號名稱
* **expr**:暫存器相對位址、程序相對地址、絕對位址或32位整數常量
* **type**:可以是以下任一(代碼16、代碼32、數據)
```AREA Prog1, CODE, READONLY
abc EQU 2 ; 將值 2 賦給符號 abc
xyz EQU label+8 ; 將地址(標籤+8)分配給符號xyz
fiq EQU 0x1C, CODE32 ;將絕對位址 0x1C 分配給符號 fiq,並將其標記為代碼marks it as code
```
* **ENTRY**
* 聲明程式的入口點
* 語法:
* 如果不存在 ENTRY,則在連結時產生警告
* 不得在單一來源檔案中使用多個 ENTRY 指令
* 並非每個原始檔都必須有 ENTRY 指令
* 如果單一來源檔案中存在多個 ENTRY => error
```AREA Prog1, CODE, READONLY
AREA ARMex, CODE, READONLY
ENTRY ; 應用程式的入口點
```
* **DCB** : 分配一個或多個字節的記憶體,並定義記憶體的初始運行時內容,同義詞為=====
* 語法:
* **expr**:計算結果為 –128 到 255 範圍內的整數或引號的字串的數值表達式,字串的字元被載入到儲存的連續位元組中。如果 DCB 後面接著指令,請使用 ALIGN 指令來確保指令對齊
* **DCW and DCWU**
* DCW 指令分配一個或多個半字記憶體,在 2 位元組邊界上對齊,並且定義記憶體的初始運行時內容
* DCWU 是相同的,只是記憶體對齊是任意的
* 語法:
* **expr**:是一個數值表達式,其計算結果為 –32768 到 65535 範圍內的整數
* 如有必要,DCW 會在第一個定義的半字之前插入inserts 一個字節填充padding,以實現 2 位元組對齊
* 如果不需要對齊alignment,請使用DCWU
* **DCD and DCDU**
* DCD指令分配allocate一個或多個記憶體字,在4位元組邊界上對齊aligned,並定義記憶體的==initial runtime contents of the memory初始運行時內容==
* DCDU 是一樣的,只是記憶體對齊是arbitrary任意的
* 語法:
* **expr**:
* A numeric expression數值表達式
* A program-relative expression與程式相關的表達式
* DCD 在第一個定義的字之前插入最多 3 個位元組的填充,以實現 4 位元組對齊
* Use DCDU, do not require alignment
範例:
```AREA Prog1, CODE, READONLY
data1 DCD 1,5,20 ; 定義 3 個單詞,其中包含十進制值 1、5 和 20
data2 DCD mem06 + 4 ; 定義 1 個包含 4 + 的單字標籤mem06的地址
coeff DCW 0xFE37, 0x8ECC ; 定義2個半字
AREA MyData, DATA, READWRITE
DCB 255 ; Now misaligned ...現在錯位了...
data3 DCDU 1,5,20 ; 定義 3 個單詞,其中包含1、5 和 20,未字對齊
```
* **ALIGN**
* 通過用零填充將當前位置與指定邊界對齊
* 語法: 
* **expr**:是一個數值表示式,計算值為 2的任意冪次 從 2⁰到2³¹
* **offset** :任何數值表達式
* 目前位置與表單的下一個位址對齊:offset + n * expr
* 如果未指定 expr,則 ALIGN 將當前位置設置為下一個字(四位元節)邊界
* 範例:
```AREA Prog1, CODE, READONLY
AREA OffsetExample, CODE
DCB 1
ALIGN 4, 3
DCB 1 ;此範例將兩個位元組放置在同一字的第一個和第四個位元組中
AREA Example, CODE, READONLY
Start LDR r6, =label1
; code
MOV pc, lr
label1 DCB 1
ALIGN
subroutine1 ; pc 現在未對齊確保子程式 1 尋址以下指令
MOV r5, #0x5
```
* **SPACE**
* Reserves保留一個歸零的記憶體塊,同義詞為%
* 語法:
* **expr** :計算結果為要保留的零位元組數
* 使用 ALIGN 指令對齊 SPACE 指令後面的任何代碼
* 範例:
```AREA Prog1, CODE, READONLY
AREA MyData, DATA, READWRITE
data1 SPACE 255 ; defines 255 bytes of zeroed store定義 255 位元組的歸零存儲
```
## CH5 Data Transfer: Loads, Stores, and Addressing數據傳輸:載入、存儲和尋址
### 載入與儲存指令
| 指令| 意義 |
| -------- | -------- |
| LDR/LDM| : LoaD Register/LoaD Multiple多個 registers |
|STR/STM |store儲存 Register/STore Multiple registers|
| MOV/MVM | MOVe/MoVe Not|
|PLD |cache preLoad緩存預載入|
| SWP |在暫存器和記憶體之間交換數據|
### 資料處理指令
```AREA Prog1, CODE, READONLY
MOV R0, #0 ; 將數值0存入R0中
ADD R3, R3, #1 ; R3=R3+1
CMP R7, #1000 ; R7-1000
BIC R9, R8, #0xFF00 ; Clear bits 8-15 of R8 and store in R9,
;ex:r8=0x25496178 => r9=0x25490078
```
CMP 功能相当于减法指令,只是不保存结果,仅仅根据计算结果对标志暫存器进行设置
```AREA Prog1, CODE, READONLY
MOV R2, R0 ; 將R0中的值給R2
ADD R4, R3, R2 ; R4=R3+R2
CMP R7, R8 ; R7-R8
```
```AREA Prog1, CODE, READONLY
MOV R2, R0, LSL #2 ; (R2=R0x4)
ADD R9, R5, R5, LSL #3 ; R9=R5+ (R5 x 2^3)
RSB R9, R5, R5, LSL #3 ; R9=(R5 x 2^3) - R5
SUB R10, R9, R8, LSR #4 ; R10=R9 - (R8/2^4)
MOV R12, R4, ROR R3 ; R12 = R4的值向右移R3個單位(以二進制值右移)
```
"**ror eax, 1**"将把暫存器eax中的二进制数向右移动1位,同时将移出的最右一位放到eax的最高位上。
#### Example: immediate and register offset
```AREA Prog1, CODE, READONLY
;Word
LDR R1, [R0] ; R1=R0所指的記憶體位置中的值(四個byte)
LDR R8, [R3, #4] ; R8 =(R3+4)所指的記憶體位置中的值
LDR R12, [R13, #-4] ; R12 =(R3-4)所指的記憶體位置中的值
STR R2, [R1, #0x100] ; 將R2中的值存到記憶體中(R1 + 0x100)的位置
STR R2, [R1], #4 ;將R2中的值存到記憶體中(R1)的位置,再令暫存器中R1=R1+4
```
```AREA Prog1, CODE, READONLY
; Byte
LDRB R5, [R9] ; 將R9所指的記憶體位置中的一個byte放入R5暫存器中(一個byte=2個位元)
; (zero top 3 bytes)
LDRB R3, [R8, #3] ; 將(R8+3)所指的記憶體位置中的一個byte放入R3暫存器中
; (zero top 3 bytes)
STRB R4, [R10, #0x200] ; 將R4暫存器中的一個byte存入(R10 + 0x200)所指的記憶體位置中
```
```AREA Prog1, CODE, READONLY
LDRH R1, [R0] ; 將[R0]所指的記憶體位置中的兩個byte放入暫存器R1中
; (zero top 2 bytes)
LDRH R8, [R3, #2] ; 將[R3+2]所指的記憶體位置中的兩個byte放入暫存器R8中
LDRH R12, [R13, #-6] ; 將[R3-6]所指的記憶體位置中的兩個byte放入暫存器R12中
STRH R2, [R1, #0x80] ; 將R2暫存器中的兩個byte存入(R1 + #0x80)所指的記憶體位置中
```
```AREA Prog1, CODE, READONLY
LDRSH R5, [R9] ; 將[R9]所指的記憶體位置中的兩個byte放入暫存器R5中
LDRSB R3, [R8, #3] ; 將[R8+3]所指的記憶體位置中的兩個byte放入暫存器R3中
LDRSB R4, [R10, #0xC1] ; 將[R10 + 0xC1]所指的記憶體位置中的兩個byte放入暫存器R4中
```
```AREA Prog1, CODE, READONLY
LDRH R11, [R1, R2] ; 將[R1+R2]所指的記憶體位置中的兩個byte放入暫存器R11中
STRH R10, [R7, -R4] ; R10暫存器中的兩個byte存入(R7 - R4)所指的記憶體位置中
LDR R11, [R1, R2] ; 將[R1+R2]所指的記憶體位置中的值放入暫存器R11中
STRB R10, [R7, -R4] ; R10暫存器中的一個byte存入(R7 - R4)所指的記憶體位置中
```
**中括號[]:記憶體位置**
Example: Scaled register offset
```AREA Prog1, CODE, READONLY
LDR R11, [R3, R5, LSL #2] ;將 [EA=R3 + (R5 x 2^2)]所指的記憶體位置中的值存入暫存器R11中
STR R7, [R1, R3, LSR #3] ; 將暫存器R7中的值存入[R1 + (R3 / 2^3)]所指的記憶體位置中
```
```AREA Prog1, CODE, READONLY
LDR R1, [R0, #4]! ;R1 =記憶體位置[EA=R0 + 4]
; then R0 = 記憶體位置
STRB R7, [R6, #-1]! ; 將暫存器R7中的一個byte存入記憶體位置[EA=R6 – 1],
; then R6 = EA
LDRSH R1, [R0, #2]! ; R1=記憶體位置[EA=R0 + 2]中的兩個byte
; then R0 = EA
LDRSB R7, [R6, #-1]! ; R7=記憶體位置[EA=R6 – 1]中的一個byte
; then R6 = EA
LDR R11, [R3, R1] ! ; R11=記憶體位置[EA=R3 +R1]中的值
; then R3 = EA
STR R7, [R1, -R3]! ; 將暫存器R7中的值存入記憶體位置[EA=R1-R3],
; then R1 = EA
```
```AREA Prog1, CODE, READONLY
LDRH R3, [R9], #2 ; Load halfword to R3 from mem[EA=R9],
; then R9 = R9 + 2
STRH R2, [R5], #8 ; Store halfword from R2 to mem[EA=R5],
; then R5 = R5 + 8
LDR R0, [R1], R2 ; Load R0 from mem[EA=R1]
; then R1 = R1 + R2
LDR R0, [R1], R2, LSL #2 ; Load R0 from mem[EA=R1]
; then R1 = R1 + R2 x 4
```
<font color="#f00">**!**</font> :
* 更新暫存器中的值
* 對於暫存器清單中的每個暫存器,它遞減或遞增一個字
<font color="#f00">register-list</font> : 用大括弧括起來的符號暫存器名稱和暫存器範圍的逗號分隔清單。
example : {r0,r1,r4-r6,pc}
Example **?**
```AREA Prog1, CODE, READONLY
STMFD r13!, {r0-r5} ; Push onto a Full Descending Stack
LDMFD r13!, {r0-r5} ; Pop from a Full Descending Stack
subroutine
STMFD sp!, {r5-r7,lr} ; Push work registers and lr
; code
BL somewhere_else
; code
LDMFD sp!, {r5-r7,pc} ; Pop work registers and pc
```
```AREA Prog1, CODE, READONLY
STMFD R13!, {R1} ;將暫存器R13中的值減4,再將R1中的值放入R13所指的記憶體位置中
```