###### tags: `組合語言`
# 組合語言共筆 12 : Data Processing 指令
這篇主要是講一些組合語言基本的計算指令
<br>
## 1. 加減運算指令
```
- 語法 :
<運算子>{<condi>}{s|S} Rd Rn Operand2
- {s|S} : 修飾詞,用以更動 CPSR 的 Flags
```
- 範例
```assembler=
### 加法 ###
add r0,r1,r2 // r0 := r1 + r2
adc r0,r1,r2 // r0 := r1 + r2 + C
### 減法 ###
sub r0,r1,r2 // r0 := r1 - r2
sbb r0,r1,r2 // r0 := r1 - r2 - C
sbc r0,r1,r2 // r0 := r1 - r2 + C - 1
### reverse 減法 ###
rsb r0,r1,r2 // r0 := r2 - r1
rsc r0,r1,r2 // r0 := r2 - r1 + C - 1
```
```
備註 :
- C : 代表 CPSR Flags 中 C (carry) 的值
- r : reverse 指將減法順序倒轉 ( ex : r1-r2 => r2-r1 )
是為了解決如果想用 Operand2 操作要減去的數,所使用的方法
```
<br>
## 2. 乘除運算指令
### 乘法指令
在乘法指令中,除了乘法外,還可加上加法功能,做線性回歸方程運算
```
- 普通乘法
MUL Rd, Rm, Rs // Rd := Rm * Rs
- 回歸運算
MLA Rd, Rm, Rs, Rn // Rd := Rm * Rs + Rn
```
### 64 Bit 乘法指令
```
- 說明
為了防止做完乘法後,數字超過 32 bit 可以存的大小,
所以這邊規劃兩個暫存器以供儲存
RdHi : 儲存較高位元資料 (32 bit)
RdLo : 儲存較低位元資料 (32 bit)
ex : 資料 = 0x1111_FFEF_1032_00EF
=> RdHi = 0x1111_FFEF
=> RdLo = 1032_00EF
```
```
- 語法
SMULL RdLo, RdHi, Rm, Rs // RdLo:RdHi = Rm * Rs // signed(有號)計算
UMULL RdLo, RdHi, Rm, Rs // RdLo:RdHi = Rm * Rs // unsigned 計算
SMLAL RdLo, RdHi, Rm, Rs // RdLo:RdHi = Rm * Rs + RdLo:RdHi // signed
UMLAL RdLo, RdHi, Rm, Rs // RdLo:RdHi = Rm * Rs + RdLo:RdHi // unsigned
```
```assembly=
@ ex:
SMULL r0, r1, r2, r3 @ r0:r1 := r2 * r3
```
### 除法
```
- 語法
SDIV Rd, Rm, Rn // Rd := Rn / Rm // signed 運算
UDIV Rd, Rm, Rn // Rd := Rn / Rm // unsigned 運算
```
<br>
## 3. 邏輯位元運算指令
邏輯位元運算,是 Bit-wise 運算
並利用邏輯指令達成
```
- 語法 :
<運算子>{<condi>}{s|S} Rd Rn Operand2
```
### AND
```
- 運算邏輯
data_1 11111100
data_2 00001110
-------------------- And
output 00001100
```
```assembly=
- 範例
AND r0,r1,r2 // r0 := r1 AND r2
```
### OR
```
- 運算邏輯
data_1 11111100
data_2 00001110
-------------------- OR
output 11111110
```
```assembly=
- 範例
ORR r0,r1,r2 // r0 := r1 OR r2
```
### XOR
```
- 運算邏輯
data_1 11111100
data_2 00001110
-------------------- XOR
output 11110010
```
```assembly=
- 範例
EOR r0,r1,r2 // r0 := r1 XOR r2
```
### BIC
```
- 運算邏輯
BIC 的運算邏輯意義 : Bit-Clear 是清除 r1 中對應 r2 為 1 的位元
寫成邏輯就是 r0 := r1 AND ( NOT r2 )
----------------------------------------------------------------
EX :
> bic r0,r1,r2
r1 = 11111111
r2 = 00001111
r0 = 11110000
- 過程
- not r2 = 11110000
- r1 and (not r2) = 11110000
```
```assembly=
- 範例
BIC r0,r1,r2 // r0 := r1 AND ( NOT r2 )
```
<br>
## 4 移動運算指令
```assembly=
MOV r0, r1 // 將 r1 資料移到 r0
MVN r0, r1 // 將 NOT(r1) 移到 r0
//
```
<br>
## 5. 比較運算指令
```assembly=
CMP r0, r1 // 利用 r1-r2 的計算值改變 flag,可以比較大,小,等於
CMN r0, r1 // 利用 r1+r2 的計算值改變 flag,可以比較是否相反
TST r0, r1 // 利用 r1 AND r2 的計算值改變 flag,可以做 bit 比較
// 'test bits'
TEQ r0, r1 // 利用 r1 XOR r2 的計算值改變 flag,可以比較是否相同
// 'Test Equivalence.'
//
```
<br>
## 6. CPSR & SPSR 操作指令
此指令可以"讀取"或是"設定" CPSR 和 SPSR 的狀態
```
- 語法
MRS Rd, CPSR{_指定範圍} // 將 CPSR 讀取進 Rd
MSR Rd, CPSR{_指定範圍} // 將 Rd 的資料移入 CPSR
```
```assembly=
@ ex :
MRS r0, CPSR // 將 CPSR 資訊讀入 r0
bic r0, r0, #0xF0000000 // 清空 CPSR
MSR CPSR_f, r0 // 將清空的 flag 段存回 CPSR
```
### 指定範圍

[組合語言共筆 14 : Register 區段與功能](/4s0PTJnfTE-loizrDNLitQ)
- Flag bits ( f )
- Status bits ( s )
- Extension bits ( x )
- Control bits ( c )
<br>
## 7. 系統指令 System Calls
```
SWI <syscall number>
```
- 此指令會要求 CPU 暫停現在的工作,並跳到指定任務,此任務會要存在指定暫存器 r7
- 此指令會將模式切換到 SVC Mode
```assembly=
@ ex :
MOV r7, #4 // 將指定任務移到 r7
SWI #0 // 暫停當前任務,並跳到 r7
// 通常 swi 的 syscall 都是 #0
```
<br>
## 8. 大拇哥模式指令 Thumb
一般情況下 ARM 都是以 32 位元來儲存指令,但其實也有提供 16 bit 的儲存方式
但比起 32 bit 儲存模式,功能會更少一些
```
BX <target_address>
```