微处理器原理与应用篇---ARM常见汇编指令

发布于:2025-06-25 ⋅ 阅读:(23) ⋅ 点赞:(0)

ARM 汇编常用指令详解与应用实例

ARM 汇编语言是嵌入式系统开发的基础,以下详细介绍常用指令的功能、语法及应用场景,并结合实例说明。

数据传输指令 MOV Rd, RnMOV Rd, #imm 将寄存器Rn中的数据或立即数imm传送到寄存器Rd
MRS Rd, CPSRMRS Rd, SPSR 将程序状态寄存器(CPSRSPSR)中的数据传送到通用寄存器Rd
MSR CPSR, RnMSR SPSR, Rn 将通用寄存器Rn中的数据传送到程序状态寄存器(CPSRSPSR)中
存储器访问指令 LDR Rd, [Rn]LDR Rd, [Rn, #offset]LDR Rd, [Rn, Rm] 从内存中加载数据到寄存器。[Rn]表示以Rn的值为地址的内存单元;[Rn, #offset]表示以Rn的值加上偏移量offset为地址的内存单元;[Rn, Rm]表示以Rn的值加上Rm的值为地址的内存单元
STR Rd, [Rn]STR Rd, [Rn, #offset]STR Rd, [Rn, Rm] 将寄存器Rd中的数据存储到内存中。存储地址的计算方式与LDR指令类似
堆栈操作指令 PUSH {R0, R1,..., Rn} 将寄存器R0R1、...、Rn中的数据依次压入栈中
POP {R0, R1,..., Rn} 从栈中弹出数据,并分别存储到寄存器RnRn - 1、...、R0
跳转指令 B label 无条件跳转到标号label处执行
BL label 跳转到标号label处执行子程序,同时将当前的PC值保存到R14LR)寄存器中
BX Rn 跳转到寄存器Rn指定的地址执行,目标地址处的指令既可以是ARM指令,也可以是Thumb指令
BEQ label Z标志位为1(即相等)时,跳转到标号label处执行
BNE label Z标志位为0(即不相等)时,跳转到标号label处执行
BLT label N标志位为1V标志位为0(即有符号数小于)时,跳转到标号label处执行
BGT label Z标志位为0N标志位等于V标志位(即有符号数大于)时,跳转到标号label处执行
算术运算指令 ADD Rd, Rn, Operand2 将寄存器Rn的值与操作数Operand2相加,结果存储在寄存器Rd
SUB Rd, Rn, Operand2 将寄存器Rn的值减去操作数Operand2,结果存储在寄存器Rd
MUL Rd, Rn, Operand2 将寄存器Rn的值与操作数Operand2相乘,结果存储在寄存器Rd
SDIV Rd, Rn, Operand2 将寄存器Rn中的有符号数除以操作数Operand2,结果存储在寄存器Rd
逻辑运算指令 AND Rd, Rn, Operand2 对寄存器Rn的值和操作数Operand2进行按位与操作,结果存储在寄存器Rd
ORR Rd, Rn, Operand2 对寄存器Rn的值和操作数Operand2进行按位或操作,结果存储在寄存器Rd
EOR Rd, Rn, Operand2 对寄存器Rn的值和操作数Operand2进行按位异或操作,结果存储在寄存器Rd
MVN Rd, Rn 对寄存器Rn的值进行按位取反操作,结果存储在寄存器Rd
1. LDR(Load Register)

功能:从内存加载数据到寄存器。
语法

LDR Rd, [Rn, #offset]   ; Rd = *(Rn + offset),基址+偏移寻址
LDR Rd, label          ; Rd = 标签地址处的值,PC相对寻址

实例

LDR R0, =0x40000000    ; R0加载立即数地址(伪指令)
LDR R1, [R0]           ; 从地址0x40000000加载数据到R1
LDR R2, [R0, #4]       ; 从地址0x40000004加载数据到R2(偏移4字节)

应用:读取外设寄存器值(如 GPIO 状态)、加载常量数据。

2. LDRB(Load Register Byte)

功能:从内存加载单字节数据到寄存器,高 24 位自动零扩展。
语法

LDRB Rd, [Rn]          ; Rd = *(Rn)(8位),零扩展为32位

实例

LDR R0, =0x40000000    
LDRB R1, [R0]          ; 从地址0x40000000加载1字节到R1低8位,高24位补0

应用:读取字符数据、访问 8 位寄存器(如 ADC 采样值)。

3. AND(Logical AND)

功能:寄存器与操作数按位与,结果存入目标寄存器。
语法

AND Rd, Rn, Rm         ; Rd = Rn & Rm
AND Rd, Rn, #immediate ; Rd = Rn & immediate

实例

AND R0, R0, #0x0F      ; 保留R0低4位,高28位清零(屏蔽操作)
AND R1, R2, R3         ; R1 = R2 & R3

应用:位掩码操作(如提取状态标志)、清除特定位。

4. ADD(Addition)

功能:寄存器加法运算。
语法

ADD Rd, Rn, Rm         ; Rd = Rn + Rm
ADD Rd, Rn, #immediate ; Rd = Rn + immediate

实例

ADD R0, R1, R2         ; R0 = R1 + R2
ADD R3, R3, #1         ; R3自增1(R3++)

应用:算术运算、地址计算(如数组索引)。

5. STR(Store Register)

功能:将寄存器数据存储到内存。
语法

STR Rd, [Rn, #offset]  ; *(Rn + offset) = Rd
STR Rd, label          ; *label = Rd

实例

LDR R0, =0x40000000    
MOV R1, #0x12345678    
STR R1, [R0]           ; 将R1的值存入地址0x40000000

应用:写外设寄存器(如配置 GPIO 输出)、保存变量到内存。

6. DCD(Define Constant Data)

功能:在内存中定义 32 位常量数据(非指令,属于伪指令)。
语法

label DCD value1, value2, ...  ; 在当前地址定义字数据

实例

DataArea DCD 0x12345678, 0x87654321  ; 定义两个32位常量
        DCD 100, 200                  ; 定义两个整数

应用:初始化数组、定义查找表(如正弦函数表)。

7. MUL(Multiply)

功能:寄存器乘法运算。
语法

MUL Rd, Rn, Rm         ; Rd = Rn * Rm(32位×32位→32位)

实例

MOV R0, #5
MOV R1, #10
MUL R2, R0, R1         ; R2 = 5 * 10 = 50

应用:数学计算(如面积、体积)、缩放操作。

8. MSR(Move to Special Register)

功能:将通用寄存器值写入特殊寄存器(如状态寄存器)。
语法

MSR special_reg, Rn    ; special_reg = Rn

实例

MOV R0, #0x13          ; 设置处理器模式为SVC(10011)
MSR CPSR_c, R0         ; 修改CPSR的低5位(模式位)

应用:系统初始化(如配置特权模式)、异常处理。

9. MOV(Move)

功能:数据传送(寄存器←寄存器 / 立即数)。
语法

MOV Rd, Rn             ; Rd = Rn
MOV Rd, #immediate     ; Rd = immediate(立即数需符合编码规则)

实例

MOV R0, R1             ; R0 = R1
MOV R2, #0xFF          ; R2 = 0x000000FF

应用:初始化寄存器、数据传递。

10. STRH(Store Register Halfword)

功能:将寄存器低 16 位存储到内存半字地址(16 位对齐)。
语法

STRH Rd, [Rn]          ; *(Rn) = Rd[15:0](半字对齐)

实例

MOV R0, #0x40000000    
MOV R1, #0x12345678    
STRH R1, [R0]          ; 将R1低16位(0x5678)存入地址0x40000000

应用:存储 16 位数据(如音频采样、16 位传感器值)。

综合实例:LED 控制与数据处理

以下代码演示如何使用上述指令实现 LED 控制和数据处理:

    AREA    Main, CODE, READONLY
    ENTRY
    
; 定义外设基址和常量
LED_BASE    DCD     0x40021000      ; GPIO端口基址
DELAY_VAL   DCD     0x00FFFFFF      ; 延时计数最大值

; 主程序
Main
    LDR R0, =LED_BASE               ; R0 = GPIO基址
    LDR R1, [R0, #0x04]             ; 读取GPIO配置寄存器
    ORR R1, R1, #0x00000003         ; 配置PA0为输出模式(0b11)
    STR R1, [R0, #0x04]             ; 写回配置寄存器
    
Loop
    ; 点亮LED
    LDR R1, [R0, #0x10]             ; 读取输出数据寄存器
    ORR R1, R1, #0x00000001         ; 设置PA0为高电平
    STR R1, [R0, #0x10]             ; 写回输出寄存器
    
    ; 延时
    LDR R2, =DELAY_VAL
    LDR R2, [R2]
Delay1
    SUBS R2, R2, #1                 ; 递减计数
    BNE Delay1                      ; 非零则继续循环
    
    ; 熄灭LED
    LDR R1, [R0, #0x10]
    BIC R1, R1, #0x00000001         ; 清除PA0位(与0xFFFFFFFF异或)
    STR R1, [R0, #0x10]
    
    ; 延时
    LDR R2, =DELAY_VAL
    LDR R2, [R2]
Delay2
    SUBS R2, R2, #1
    BNE Delay2
    
    B Loop                          ; 无限循环
    END

指令对比与注意事项

指令 操作类型 数据宽度 内存访问方式
LDR 加载 32 位(字) 字对齐
LDRB 加载 8 位(字节) 任意地址
STR 存储 32 位(字) 字对齐
STRH 存储 16 位(半字) 半字对齐(偶地址)

  • 立即数限制:MOV 指令的立即数需符合 “8 位数值循环右移偶数位” 规则(如 0xFF00 可表示为 0xFF 右移 8 位),否则需用 LDR 伪指令加载。
  • 内存对齐:STR/STRH/LDR/LDRH 需遵循对齐规则,否则可能触发硬件异常。

掌握这些指令是 ARM 汇编编程的基础,可实现从简单外设控制到复杂算法的各类功能。


网站公告

今日签到

点亮在社区的每一天
去签到