无论是数据运算还是逻辑运算,需要满足如下格式:
<操作码> <目标寄存器> <第一操作寄存器> <第二操作数>
- 操作码: 表示执行哪种操作(加减乘)
- 目标寄存器: 用于存储运算的结果
- 第一操作寄存器: 存储第一个参与运算的数据(只能写寄存器)
- 第二操作数: 第二个参与运算的数据(可以是寄存器也可以是立即数)
目录
一、数据运算指令
1、加法指令
(1) 加法指令 ADD (相加时不考虑进位)
(2) 加法指令ADDS(保留进位状态)
(3) 带进位加法指令 ADC(相加时考虑进位)
2、减法指令
(1) 减法指令 SUB
(2) 减法指令SUBS(保留借位状态)
(3) 带借位减法指令 SBC
(4) 逆向减法指令 RSB
3、乘法指令 MUL
二、逻辑运算指令
1、按位与指令 AND
2、按位或指令 ORR
3、按位异或指令 EOR
4、左移指令 LSL
5、右移指令 LSR
三、拓展指令
1、位清零指令 BIC
2、运算指令与其他指令的混合使用
一、数据运算指令
1、加法指令
(1) 加法指令 ADD (相加时不考虑进位)
ADD在做加法运算时,不考虑任何进位,包含了两方面。
- ADD 运算产生的进位,会忽略(CPSR寄存器的C状态位不会改变)
- 如果要记录产生的进位,需改为 ADDS 指令
- 上一次运算产生的进位,也会忽略
- 如果要考虑上一次的进位,需改为 ADC 指令
ADD R1, R2, R3 @ R1 = R2 + R3
ADD R1, R2, #5 @ R1 = R2 + 5
ADD R1, #7, #5 @ 非法
ADD R1, #7, R2 @ 非法
注意:正常情况下使用的指令都是ADD,寄存器一次可以处理32bit,如果是处理64bit 的数才会需要用到ADDS 和 ADC。
(2) 加法指令ADDS(保留进位状态)
如果ADD的运算结果产生了进位,默认是不保存的,即不会更新到CPSR寄存器;如果要更新到CPSR寄存器,需要使用指令ADDS。
使用格式和ADD完全一样:
ADDS R1, R2, R3 @ R1 = R2 + R3
(3) 带进位加法指令 ADC(相加时考虑进位)
ADC在做加法运算时,会考虑上一次运算产生的进位。
ADC R1, R2, R3 @ R1 = R2 + R3 + CPSR的C状态位
2、减法指令
(1) 减法指令 SUB
SUB和上面ADD类似,在做减法运算时,不考虑任何借位:
- SUB 运算产生的借位,会忽略(CPSR寄存器的C状态位不会改变)
- 如果要记录产生的借位,需改为 SUBS 指令
- 上一次运算产生的借位,也会忽略
- 如果要考虑上一次的借位,需改为 SBC 指令
SUB R1, R2, R3 @ R1 = R2 - R3
SUB R1, R2, #1 @ R1 = R2 - 1
(2) 减法指令SUBS(保留借位状态)
SUB产生的借位,默认不保存,即不会更新到CPSR寄存器;如果要更新到CPSR寄存器,需要使用指令SUBS。
SUBS R1, R2, R3 @ R1 = R2 - R3
(3) 带借位减法指令 SBC
SBC 在做减法运算时,会考虑上一次运算产生的借位
SBC R1, R2, R3 @ R1 = R2 - R3 - (!CPSR的C状态位)
(4) 逆向减法指令 RSB
减法指令ADD只能是一个寄存器减去一个立即数,逆向减法指令可以让一个立即数减去一个寄存器。但是依然不能违背最初的格式。
RSB R1, R2, #5 @R1 = 5 - R2
3、乘法指令 MUL
乘法指令比较特殊,只能是两个寄存器相乘
MUL R1, R2, R3 @R1 = R2 * R3
二、逻辑运算指令
1、按位与指令 AND
AND R1, R2, R3 @ R1 = R2 & R3
2、按位或指令 ORR
ORR R1, R2, R3 @ R1 = R2 | R3
3、按位异或指令 EOR
EOR R1, R2, R3 @ R1 = R2 ^ R3
4、左移指令 LSL
LSL R1, R2, 1 @ R1 = R2 << 1
5、右移指令 LSR
LSR R1, R2, 1 @ R1 = R2 >> 1
三、拓展指令
上述指令都是可以在C语言中找到对应的,汇编语言也存在自己独有的指令
1、位清零指令 BIC
位清零可以将 “指定比特位” 置 0
MOV R2, #0xFF @ R2 = 0xFF
BIC R1, R2, #0x0F @ 将R2后四位清零,结果放入 R1 =》 R1 = R2 & (~0x0F)
R2 中保存的是 0xFF,转化成二进制:1111 1111
0x0F 转换成二进制形式: 0000 1111
最终结果: 1111 0000
0x0F后四位是1,说明要把R2后四位置 0,得到的运算结果放入 R1(0xF0)
2、运算指令与其他指令的混合使用
MOV R1, R2, LSL #1
MOV 的格式是 MOV <目标寄存器> <第一操作数>
- 目标寄存器:R1
- 第一操作数:R2, LSL #1
- 这里已经可以猜出个大概了,其实就是LSL将R2寄存器左移1位,其结果作为第一操作数