← 返回 计组与微机控制

计组与微机控制

5.0 ARM 指令系统和 x86 汇编

5.0 ARM 指令系统和 x86 汇编

一.X86汇编语言:

5.0 ARM 指令系统和 x86 汇编 图 15.0 ARM 指令系统和 x86 汇编 图 25.0 ARM 指令系统和 x86 汇编 图 35.0 ARM 指令系统和 x86 汇编 图 4

二.ARM指令集:

ARM 指令可以按功能分成:

| 类别 | 作用 |

| 数据传送指令 | 在寄存器之间传送数据,或装载立即数 |

| 存储器访问指令 | 在寄存器和内存之间传送数据 |

| 算术运算指令 | 加、减、乘、除等 |

| 逻辑运算指令 | 与、或、异或、取反、位清除 |

| 移位和循环指令 | 左移、右移、循环移位 |

| 比较和测试指令 | 设置条件标志,不保存运算结果 |

| 分支指令 | 修改 PC,实现跳转、函数调用和返回 |

| 伪指令 | 汇编器辅助生成真实指令 |

2. 数据传送指令

数据传送指令主要在寄存器之间移动数据。

| 指令 | 含义 |

| `MOV Rd, Operand2` | 把操作数送入 Rd |

| `MVN Rd, Operand2` | 把操作数按位取反后送入 Rd |

| `MRS Rd, PSR` | 从程序状态寄存器读到通用寄存器 |

| `MSR PSR, Rm` | 把通用寄存器写入程序状态寄存器 |

例子:

MOV R0, R1
MOV R0, #0x12

MVN R0, #0

5.0 ARM 指令系统和 x86 汇编 图 55.0 ARM 指令系统和 x86 汇编 图 6

注意:

- `MOV` 不访问内存,只在寄存器或立即数之间传递。

- 大立即数不一定能被一条 `MOV` 编码,可能需要 `LDR Rd, =常数` 伪指令。

3. 单寄存器访存指令 LDR/STR

ARM 是典型 Load/Store 架构:

> 普通算术逻辑指令通常只能处理寄存器,访问内存要用 LDR/STR。

| 指令 | 含义 || `LDR Rd, [Rn]` | 从 Rn 指向的地址读一个字到 Rd |

| `STR Rd, [Rn]` | 把 Rd 的值写到 Rn 指向的地址 |

| `LDRB/STRB` | 按字节读写 |

| `LDRH/STRH` | 按半字读写 |

| `LDRSB/LDRSH` | 读字节/半字并符号扩展 |

5.0 ARM 指令系统和 x86 汇编 图 7

例子:

LDR R0, [R1]
STR R0, [R2]

含义:

R0 = *(uint32_t *)R1

*(uint32_t *)R2 = R0

5.0 ARM 指令系统和 x86 汇编 图 85.0 ARM 指令系统和 x86 汇编 图 9

算术运算指令

| 指令 | 含义 |

| `ADD` | 加法 |

| `ADC` | 带进位加法 |

| `SUB` | 减法 |

| `SBC` | 带借位减法 |

| `RSB` | 反向减法 |

| `MUL` | 乘法 |

| `SDIV/UDIV` | 有符号/无符号除法 |

例子:

ADD R0, R1, R2
SUB R0, R1, #1

加 `S` 后缀会更新条件标志:

ADDS R0, R1, R2

SUBS R0, R0, #1

5.0 ARM 指令系统和 x86 汇编 图 10

逻辑运算指令

| 指令 | 含义 |

| `AND` | 按位与 |

| `ORR` | 按位或 |

| `EOR` | 按位异或 |

| `BIC` | 位清除,`Rn & ~Operand2` |

| `MVN` | 按位取反 |

5.0 ARM 指令系统和 x86 汇编 图 11

常见寄存器配置写法:

ORR R1, R1, #0x01

BIC R1, R1, #0x02

含义:

- `ORR` 用来置 1;

- `BIC` 用来清 0。

移位和循环指令

| 指令 | 含义 |

| `LSL` | 逻辑左移,低位补 0 |

| `LSR` | 逻辑右移,高位补 0 |

| `ASR` | 算术右移,高位补符号位 |

| `ROR` | 循环右移 |

| `RRX` | 带进位循环右移 |

5.0 ARM 指令系统和 x86 汇编 图 12

常见用途:

- 快速乘除 2 的幂;

- 生成位掩码;

- 操作寄存器字段;

- 提取或拼接二进制字段。

例子:

LSL R0, R1, #2

含义:`R0 = R1 << 2`。

位域处理指令

位域处理用于操作寄存器中的一段连续二进制位。

常见指令:

| 指令 | 含义 |

| `BFC` | 清除一段位域 |

| `BFI` | 把一个寄存器的低位插入到目标位域 |

| `UBFX` | 无符号提取位域 |

| `SBFX` | 有符号提取位域 |

STM32 寄存器配置经常要处理“某几位为一个字段”,位域思想非常重要。

例如 GPIO 模式寄存器中,每个引脚占 2 位:

MODER[2n+1 : 2n]

配置某个引脚时,本质就是清除这 2 位,再写入目标模式值。