###### 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 ``` ### 指定範圍 ![](https://i.imgur.com/bOVevWr.png) [組合語言共筆 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> ```