数据处理指令
@ 汇编中的符号
@ 1.指令: 能够编译生成一条32位的机器码,且能被CPU识别和执行
@ 2.伪指令:本身不是指令,编译器可以将其替换成若干条等效指令
@ 3.伪操作:不会生成代码,只是在编译之前告诉编译器怎么编译
@ ARM指令
@ 1.数据处理指令: 数学运算、逻辑运算
@ 2.跳转指令: 实现程序的跳转,本质就是修改了PC寄存器
@ 3.Load/Srore指令: 访问(读写)内存
@ 4.状态寄存器传送指令:访问(读写)CPSR寄存器
@ 5.软中断指令: 触发软中断异常
@ 6.协处理器指令: 操控协处理器的指令
@ *****************************************************************
.text @表示当前段为代码段
.global _start @声明_start为全局符号
_start: @汇编程序的入口
@ 1.指令:能够编译生成一条32位的机器码,且能被CPU识别和执行
@ 1.1 数据处理指令:数学运算、逻辑运算
一、数据处理指令总结
1. 数据搬移
指令 | 示例 | 说明 |
---|---|---|
MOV | MOV R1, #1 | 赋值 |
MVN | MVN R0, #0xFF | 按位取反后赋值 |
2. 运算指令格式
操作码 目标寄存器, 第一操作寄存器, 第二操作数
3. 基本运算
指令 | 示例 | 说明 |
---|---|---|
ADD | ADD R1, R2, R3 | 加法 |
SUB | SUB R1, R2, R3 | 减法 |
RSB | RSB R1, R2, #3 | 逆向减法(3 - R2) |
MUL | MUL R1, R2, R3 | 乘法(只能是寄存器) |
4. 位运算
指令 | 示例 | 说明 |
---|---|---|
AND | AND R1, R2, R3 | 按位与 |
ORR | ORR R1, R2, R3 | 按位或 |
EOR | EOR R1, R2, R3 | 按位异或 |
BIC | BIC R1, R2, #0x0F | 位清零(第二操作数为掩码) |
5. 移位
指令 | 示例 | 说明 |
---|---|---|
LSL | LSL R1, R2, #1 | 逻辑左移 |
LSR | LSR R1, R2, #1 | 逻辑右移 |
6. 扩展语法
示例 | 说明 |
---|---|
MOV R1, R2, LSL #1 | 移位后赋值 |
二、标志位与后缀
默认不影响标志位(N、Z、C、V)
加
S
后缀可影响标志位,如:ADDS
、SUBS
三、64 位运算(带进位/借位)
1. 带进位加法(ADC)
ADDS R5, R1, R3 @ 低32位相加,更新标志
ADC R6, R2, R4 @ 高32位相加,加进位
(ADC适用于多字节(如32位)加法,ADC执行后,CF(进位标志)会被更新)
2. 带借位减法(SBC)
SUBS R5, R1, R3 @ 低32位相减,更新标志
SBC R6, R2, R4 @ 高32位相减,减借位
(用于处理超过32位的减法运算。当需要借位时,进位标志会被清零)
四、立即数
包含在指令中,速度快
不能是任意 32 位数,有局限性
编译器可能将非法立即数替换为多条指令
MOV R1,#1 ,#1是立即数,立即数的本质是包含在指令当中的数,
这条指令,经过编译器编译后,会生成一条32位的机器码,1包含在机器码中了,当CPU执行这条MOV指令时,CPU会把这条机器码读到CPU内部,所以CPU执行这条指令时,就会把机器码中的1提取出来,放到CPU内部中的R1里面
@ 数据搬移指令
@ MOV R1, #1
@ R1 = 1
@ MOV R2, R1
@ R2 = R1
@ MVN R0, #0xFF
@ R0 = ~0xFF
@ 立即数
@ 立即数的本质就是包含在指令当中的数,属于指令的一部分
@ 立即数的优点:取指的时候就可以将其读取到CPU,不用单独去内存读取,速度快
@ 立即数的缺点:不能是任意的32位的数字,有局限性
@ MOV R0, #0x12345678
@ MOV R0, #0x12
@ 编译器替换
@ MOV R0, #0xFFFFFFFF
@ 数据运算指令基本格式
@ 《操作码》《目标寄存器》《第一操作寄存器》《第二操作数》
@ 操作码 指示执行哪种运算
@ 目标寄存器: 存储运算结果
@ 第一操作寄存器:第一个参与运算的数据(只能是寄存器)
@ 第二操作数: 第二个参与运算的数据(可以是寄存器或立即数)
@ 加法指令
@ MOV R2, #5
@ MOV R3, #3
@ ADD R1, R2, R3
@ R1 = R2 + R3
@ ADD R1, R2, #5
@ R1 = R2 + 5
@ 减法指令
@ SUB R1, R2, R3
@ R1 = R2 - R3
@ SUB R1, R2, #3
@ R1 = R2 - 3
@ 逆向减法指令
@ RSB R1, R2, #3
@ R1 = 3 - R2
@ 乘法指令
@ MUL R1, R2, R3
@ R1 = R2 * R3
@ 乘法指令只能是两个寄存器相乘
@ 按位与指令
@ AND R1, R2, R3
@ R1 = R2 & R3
@ 按位或指令
@ ORR R1, R2, R3
@ R1 = R2 | R3
@ 按位异或指令
@ EOR R1, R2, R3
@ R1 = R2 ^ R3
@ 左移指令
@ LSL R1, R2, R3
@ R1 = (R2 << R3)
@ 右移指令
@ LSR R1, R2, R3
@ R1 = (R2 >> R3)
@ 位清零指令
@ MOV R2, #0xFF
@ BIC R1, R2, #0x0F
@ 第二操作数中的哪一位为1,就将第一操作寄存器的中哪一位清零,然后将结果写入目标寄存器
@ 格式扩展
@ MOV R2, #3
@ MOV R1, R2, LSL #1
@ R1 = (R2 << 1)
@ 数据运算指令对条件位(N、Z、C、V)的影响
@ 默认情况下数据运算不会对条件位产生影响,在指令后加后缀”S“才可以影响
@ 带进位的加法指令
@ 两个64位的数据做加法运算
@ 第一个数的低32位放在R1
@ 第一个数的高32位放在R2
@ 第二个数的低32位放在R3
@ 第二个数的高32位放在R4
@ 运算结果的低32位放在R5
@ 运算结果的高32位放在R6
@ 第一个数
@ 0x00000001 FFFFFFFF
@ 第二个数
@ 0x00000002 00000005
@ MOV R1, #0xFFFFFFFF
@ MOV R2, #0x00000001
@ MOV R3, #0x00000005
@ MOV R4, #0x00000002
@ ADDS R5, R1, R3
@ ADC R6, R2, R4
@ 本质:R6 = R2 + R4 + 'C'
@ 带借位的减法指令
@ 第一个数
@ 0x00000002 00000001
@ 第二个数
@ 0x00000001 00000005
@ MOV R1, #0x00000001
@ MOV R2, #0x00000002
@ MOV R3, #0x00000005
@ MOV R4, #0x00000001
@ SUBS R5, R1, R3
@ SBC R6, R2, R4
@ 本质:R6 = R2 - R4 - '!C'