ARM指令集——數據處理指令
數據處理指令有:
MOV、ADD、ADDS、ADC、SUB、
SUBS、SBC、RSB、MUL、AND、
ORR、EOR、BIC、CMP、TST、
TEQ、LSL、LSR、ASR、RORV
數據處理指令語法
-
<操作{<cond>}{S}> <Rd>, <Rn>, <Operand2>
-
<操作碼> <目標寄存器Rd> <第一操作寄存器Rn> <第二操作數Operand2>
-
;第一個位置必須是寄存器,第二操作數可以是寄存器,也可以是立即數
數據傳送指令 MOV
-
mov r1, #0x1 ;r1 = 0x1 0x1 是立即數
-
mov r2, r1 ;r2 = r1
-
mvn r3, r2 ;r3 = ~r2
-
mov r1, 0xffffff00 ;0xffffff00 不是立即數,只是編譯器在編譯階段對其進行了替換
-
mvn r1, 0x000000ff ;替換的指令
-
-
-
-
;立即數的本質是包含於指令中的數,占用指令本身的空間
加法指令 ADD
-
;加法指令執行時,若沒有進位 CPSR 'C' 位置 0
-
mov r0,
-
mov r1,
-
add r2, r1, r0 ;r2 = r1 + r0
-
add r2, r1,
數據操作對CPSR的影響
-
;默認情況下,數據處理指令不影響條件碼標志位,但可以選擇通過添加“S”來影響標志位。
-
mov r1, #0mov r2, #-1
-
adds r3, r1, r2
帶進位的加法指令 ADC
-
;兩個 64位數相加,第一個64位的低32位放在 r0,高位放到 r1,第二個64位數的低32位放在 r2 高32位放在 r3
-
;編寫代碼實現兩個 64位數的和,結果的低32位放在 r4 高32位放在 r5
-
mov r 0, #0xfffffffe ;第一個數的低32位
-
mov r1, #1 ;第一個數的高32位
-
mov r2, #0x5 ;第二個數的低32位
-
mov r3, #1 ;第二個數的高32位
-
adds r4, r 0, r2
-
adc r5, r1, r3 ; adc運算的實質是 r5 = r1 + r3 + 'C' 'C'位 CPSR 進位標志
減法指令 SUB
-
;減法指令執行時,沒有借位時 CPSR 'C' 位置 1
-
mov r 0, #5
-
mov r1, #3
-
sub r2, r0, r1 ;r2 = r0 - r1
帶借位的減法指令 SBC
-
mov r0, #1 ;第一個數的低32位
-
mov r1, #3 ;第一個數的高32位
-
mov r2, #3 ;第二個數的低32位
-
mov r3, #1 ;第二個輸的高32位
-
subs r4, r0, r2
-
sbc r5, r1, r3
逆向減法指令 RSB
-
mov r0, #3
-
rsb r1, r0, #5 ;r1 = 5 - r0
乘法指令 MUL
-
;為了提高效率,任何乘法指令不可以使用立即數
-
mov r0, #3
-
mov r1, #5
-
mov r2, r0, r1 ;r2 = r0 * r1
乘——累加指令 MLA
mla r3 ,r0, r1, r2 ;r3 = (r0 * r1) + r2
邏輯與指令 AND
-
mov r0, #0xf0
-
mov r1, #0x0f
-
and r2, r0, r1 ;r2 = r0 & r1
邏輯或指令 ORR
ORR指令的格式為:ORR{條件}{S} 目的寄存器,操作數1,操作數2
ORR指令用於在兩個操作數上進行邏輯或運算,並把結果放置到目的寄存器中。操作數1應該是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令常用於設置操作數1的某些位。
指令示例:ORR R0,R0,#3;該指令設置R0的0、1位,其余位保持不變。
orr r0,r0,#0xd3
0xd3=1101 0111
將r0與0xd3作算數或運算,然后將結果返還給r0,即把r0的bit[7:6]和bit[4]和bit[2:0]置為1。
-
mov r0, #0xf0
-
mov r1, #0x0f
-
orr r2, r0, r1 ;r2 = r0 | r1
邏輯異或運算指令 EOR
-
mov r0, #0xf0
-
mov r1, #0x0f
-
eor r2, r0, r1 ;r2 = r0 ^ r1
位清零指令 BIC
指令格式:BIC{cond}{S} Rd,Rn,operand2
BIC指令將Rn 的值與操作數operand2 的反碼按位邏輯”與”,結果存放到目的寄存器Rd 中。指令示例:BIC R0,R0,#0x0F ;將R0最低4位清零,其余位不變。
-
mov r0, #0xff
-
bic r0, r0, #0xf ;第二個操作數的每一位為 1 就把第一個操作數對應的位清零
比較指令 CMP
cmp(compare)指令進行比較兩個操作數的大小
例:cmp oprd1,oprd2
為第一個操作減去第二個操作數,但不影響第兩個操作數的值,它影響flag的CF,ZF,OF,AF,PF
我們怎么判斷大小呢?若執行指令后
(1)ZF
ZF=1 這個簡單,則說明兩個數相等,因為zero為1說明結果為0。
(2)CF
當無符號時:
CF=1 則說明了有進位或借位,cmp是進行的減操作,故可以看出為借位,所以,此時oprd1<oprd2
CF=0 則說明了無借位,但此時要注意ZF是否為0,若為0,則說明結果不為0,故此時oprd1>oprd2
當有符號時:
若SF=0,OF=0 則說明了此時的值為正數,沒有溢出,可以直觀的看出,oprd1>oprd2
若SF=1,OF=0 則說明了此時的值為負數,沒有溢出,則為oprd1<oprd2
若SF=0,OF=1 則說明了此時的值為正數,有溢出,可以看出oprd1<oprd2
若SF=1,OF=1則說明了此時的值為負數,有溢出,可以看出oprd1>oprd2
最后兩個可以作出這種判斷的原因是,溢出的本質問題:
兩數同為正,相加,值為負,則說明溢出
兩數同為負,相加,值為正,則說明溢出
故有,正正得負則溢出,負負得正則溢出
補充: 兩數相減,同號,則不溢出;兩數為異號,結果與減數符號相同,則溢出。
-
;實質是一條減法指令
-
;沒有目標 register,用來比較兩個數是否相等,結果放到 CPSR 的 'Z' 位判斷
-
mov r0, #2
-
mov r1, #1
-
cmp r0, r1
位測試指令 TST
-
;實質是與運算 常用於用來測試某一位或某幾位是 0 還是 1,結果通過 CPSR 的 'Z' 位判斷
-
tst r0, #0x3
相等測試指令 TEQ
-
;實質是異或運算,測試兩個數是否相等,兩個數相等時異或結果位 0,通過 CPSR 的 'Z' 位判斷
-
teq r 0, r1
移位指令 LSL、LSR、ASR、ROR
-
;需要與mov配合,不能夠單獨使用
-
mov r0, #0xff
-
mov r1, r0, lsl #4 ;將 r0 邏輯左移 4 位放入 r1 中
-
;LSL 邏輯左移:高位移出,低位補零
-
;LSR 邏輯右移:低位移出,高位補零
-
;ASR 算是右移:低位移出,高位補符號位
-
;ROR 循環右移:低位移出,高位補低位移出位