ARM 汇编入门:从基础指令到实战示例

1. 引言

ARM 汇编语言是嵌入式开发、底层系统编程和逆向工程中不可或缺的基础技能。本文面向初学者,从 ARM 处理器的基本架构出发,逐步讲解常用指令、寄存器、寻址方式以及一个完整的汇编程序示例,帮助读者快速建立 ARM 汇编的整体认知。

2. ARM 架构基础

ARM 是一种精简指令集计算机(RISC)架构,其设计理念是让指令集保持简洁、规整,从而在低功耗的同时获得较高的执行效率。ARM 处理器广泛应用于移动设备、嵌入式系统、物联网终端等领域。

ARM 架构具有以下显著特点:

  • 固定指令长度:ARM 模式下每条指令固定为 32 位,便于流水线取指和译码。
  • 大量通用寄存器:提供 16 个 32 位通用寄存器(R0-R15),其中部分寄存器有特殊用途。
  • 加载/存储架构:只有加载(LDR)和存储(STR)指令可以访问内存,其余指令均在寄存器之间完成运算。
  • 条件执行:大多数指令可以附带条件码,根据标志位决定是否执行,减少分支跳转。

3. 寄存器与工作模式

ARM 处理器拥有 16 个 32 位通用寄存器,分别命名为 R0 到 R15。其中部分寄存器承担特殊功能:

寄存器 别名 用途说明
R0-R12 通用寄存器 用于存放数据、地址和中间运算结果
R13 SP 栈指针寄存器,指向当前栈顶
R14 LR 链接寄存器,保存子程序返回地址
R15 PC 程序计数器,指向当前正在执行的指令地址

此外,ARM 处理器还包含一个当前程序状态寄存器(CPSR),用于保存条件标志位(N、Z、C、V)、中断禁止位以及当前处理器模式等信息。

4. 常用指令详解

ARM 汇编指令数量较多,但初学者只需掌握以下几类核心指令即可编写大部分程序。

4.1 数据传送指令

armasm 复制代码
MOV R0, #5        @ 将立即数 5 送入 R0
MOV R1, R0        @ 将 R0 的值复制到 R1
LDR R2, =0x1234   @ 将常量 0x1234 加载到 R2
STR R0, [R3]      @ 将 R0 的值存储到 R3 指向的内存地址

4.2 算术运算指令

armasm 复制代码
ADD R0, R1, R2    @ R0 = R1 + R2
SUB R0, R1, #1    @ R0 = R1 - 1
MUL R0, R1, R2    @ R0 = R1 * R2
ADC R0, R1, R2    @ R0 = R1 + R2 + 进位标志

4.3 逻辑运算指令

armasm 复制代码
AND R0, R1, R2    @ R0 = R1 与 R2
ORR R0, R1, R2    @ R0 = R1 或 R2
EOR R0, R1, R2    @ R0 = R1 异或 R2
MVN R0, R1        @ R0 = R1 按位取反

4.4 分支跳转指令

armasm 复制代码
B   label         @ 无条件跳转到 label
BEQ label         @ 相等时跳转(Z 标志为 1)
BNE label         @ 不相等时跳转(Z 标志为 0)
BL  func          @ 跳转到 func 并保存返回地址到 LR

5. 寻址方式

ARM 汇编提供了多种寻址方式,用于灵活地访问内存和寄存器中的数据。

  • 立即数寻址 :操作数直接写在指令中,如 MOV R0, #100
  • 寄存器寻址 :操作数存放在寄存器中,如 MOV R1, R0
  • 寄存器间接寻址 :寄存器存放内存地址,如 LDR R0, [R1]
  • 基址变址寻址 :基址寄存器加偏移量,如 LDR R0, [R1, #4]
  • 前/后变址寻址 :先更新地址再访问,或先访问再更新地址,如 LDR R0, [R1, #4]!

6. 完整汇编程序示例

下面是一个完整的 ARM 汇编程序,演示如何计算 1 到 10 的累加和,并将结果存入指定寄存器。

armasm 复制代码
    AREA    Sum, CODE, READONLY
    ENTRY

Start
    MOV     R0, #1        @ 循环变量 i,从 1 开始
    MOV     R1, #10       @ 循环上限 n = 10
    MOV     R2, #0        @ 累加和 sum = 0

Loop
    ADD     R2, R2, R0    @ sum = sum + i
    ADD     R0, R0, #1    @ i = i + 1
    CMP     R0, R1        @ 比较 i 与 n
    BLE     Loop          @ 若 i <= n,继续循环

    MOV     R0, R2        @ 将结果放入 R0
    END

该程序的核心逻辑是:使用 R0 作为循环计数器,R1 保存循环上限,R2 保存累加结果。每次循环将当前计数值累加到 R2,然后递增计数器并与上限比较,直到计数器超过上限为止。

7. 条件执行与标志位

ARM 汇编的一大特色是条件执行。大多数数据处理指令可以附带条件码,只有满足条件时才真正执行。条件码由 CPSR 中的标志位决定。

条件码 含义 标志位条件
EQ 相等 Z = 1
NE 不相等 Z = 0
GT 有符号大于 Z = 0 且 N = V
LT 有符号小于 N 不等于 V
GE 有符号大于等于 N = V
LE 有符号小于等于 Z = 1 或 N 不等于 V

条件执行可以减少分支指令的使用,提高代码密度和执行效率。例如,下面的代码使用条件执行实现两个数取较大值的功能:

armasm 复制代码
    CMP     R0, R1        @ 比较 R0 与 R1
    MOVGT   R2, R0        @ 若 R0 > R1,则 R2 = R0
    MOVLE   R2, R1        @ 若 R0 <= R1,则 R2 = R1

8. 栈操作与子程序调用

在 ARM 汇编中,子程序调用通过 BL 指令实现,返回地址自动保存到 LR 寄存器。子程序返回时使用 MOV PC, LR 或 BX LR 指令。

armasm 复制代码
    AREA    Func, CODE, READONLY
    ENTRY

Start
    MOV     R0, #5
    MOV     R1, #3
    BL      AddFunc       @ 调用子程序
    MOV     R2, R0        @ 结果存入 R2
    B       Stop

AddFunc
    ADD     R0, R0, R1    @ R0 = R0 + R1
    MOV     PC, LR        @ 返回调用点
    END

当子程序内部需要嵌套调用其他子程序时,必须先将 LR 压栈保存,否则返回地址会被覆盖。栈操作使用 PUSH 和 POP 指令:

armasm 复制代码
    PUSH    {LR}          @ 保存返回地址
    BL      OtherFunc     @ 嵌套调用
    POP     {PC}          @ 恢复返回地址并返回

9. 总结

本文介绍了 ARM 汇编的基础知识,包括架构特点、寄存器结构、常用指令、寻址方式、条件执行以及子程序调用等内容。掌握这些基础后,读者可以进一步学习 ARM 的异常处理、中断机制、Thumb 指令集以及汇编与 C 语言的混合编程等进阶主题。

建议初学者在真实开发板或模拟器(如 QEMU、Keil MDK)上动手实践,通过编写和调试实际程序来加深对 ARM 汇编的理解。

相关推荐
索端阳4 小时前
ARM Day02 学习总结:ARM汇编基础核心知识点梳理
汇编·学习·arm
Awh-4 小时前
ARM裸机开发 Day01 学习笔记
arm开发·arm·arm裸机
2301_815091015 小时前
ARM体系结构学习笔记(一):从硬件基础、寄存器到三级流水线
arm·嵌入式开发
an12321217 小时前
ARM汇编学习笔记 Day02
arm开发·arm
xx~t8 小时前
嵌入式——ARM——汇编1
linux·汇编·arm开发·嵌入式硬件·arm
学linux的QQ蛋8 小时前
零基础吃透ARM体系架构与底层原理
arm
H_oRIZoN_9 小时前
Linux入门DAY44 ARM 入门 Day02|ARM 汇编指令、模式切换、栈操作、汇编 C 混合编程
linux·单片机·嵌入式硬件·arm·linux应用编程
susplus19 小时前
【初识ARM】ARM相关基础概念
学习·arm
myy-learn21 小时前
ARM-知识扫盲1
arm