You are on page 1of 279

第2章

ARM 体系结构
2.1 ARM 体系结构简介
 ARM 公司

ARM 是 Advanced RISC Machines 的缩写,它


是英国一家微处理器行业的知名企业, 1991 年成立
于英国剑桥,专门从事基于 RISC 技术的芯片设计和
开发。

公司的特点是只设计芯片,而不直接生产。
它将技术授权给世界上许多著名的半导体、软件
和 OEM 厂商,并提供服务。
将技术授权给
芯片厂商

...
加入适当外围电路形成
各具特色的 ARM 芯片

到目前为止已累计销售了超过 150 亿枚基于 ARM 的芯片,向


200 多家公司出售了 600 个处理器许可证。
采用 RISC 架构的 ARM 微处理器的特点:
支持 ARM ( 32 位)和 Thumb ( 16 位)双指令集;
指令采用 3 级( ARM7 ) /5 级( ARM9 )流水线;
具有指令 cache 和数据 cache ;

支持大端格式和小端格式两种存储字数据的方法;

支持字节( byte , 8 位)、半字( half , 16 位)


和字( word , 32 位) 3 种数据格式;
 支持 7 种处理器模式(用户、系统、管理、中止、未定义、中断
和快中断)
嵌入了在线仿真逻辑,便于 JTAG 使用 ;

具有片上总线 AMBA ( AHB 、 ASB 、 APB )


采用存储器映像 I/O 方式,把 I/O 端口地址作为特殊的存储器地
址;
具有协处理器接口,允许接 16 个协处理器;

低电源电压
ARM 微处理器包括 ARM7 、 ARM9 、 ARM11 、
Cortex-A (高性能)、 Cortex-R (实时)、
Cortex-M (低成本低功耗)、 SecurCore (安全)
等系列处理器。
典 31 个 32 位通用寄存器及 6 位状态寄存器
指令译码及控制逻辑


A
R
M

系 32 位 ALU
32×8 位乘法器 32×32 位桶形移位寄存器

构 指令流水线和数据/地址寄存器等



图 2.1.1 ARM 体系结构方框图


主要部件
 1 . ALU
 由两个操作数锁存器、加法器、逻辑功能、结果及零检测逻辑构
成。

 2 .桶形移位寄存器
 ARM 采用了 32×32 位桶形移位寄存器,左移/右移 n 位、环移 n
位和算术右移 n 位等都可以一次完成,可以有效的减少移位的延迟时
间。

 3 .高速乘法器
 ARM 为了提高运算速度,采用两位乘法的方法, 2 位乘法可根据
乘数的 2 位来实现“加-移位”运算。 ARM 的高速乘法器采用 32×8
位的结构,完成 32×2 位乘法也只需 5 个时钟周期。
 4 .浮点部件
 在 ARM 体系结构中,浮点部件作为选件可根据需要
选用, FPA10 浮点加速器以协处理器方式与 ARM 相连,并
通过协处理器指令的解释来执行。

 5 .控制器
 ARM 的控制器采用硬接线的可编程逻辑阵列 PLA ,其输
入端有 14 根、输出端有 40 根,分散控制 Load/Store 多路
、乘法器、协处理器以及地址、寄存器 ALU 和移位器。

 6 .寄存器
 ARM 内含 37 个寄存器,包括 31 个通用 32 位寄存器和
6 个状态寄存器。
2.2 ARM 微处理器结构
 ARM 处理器核简介

ARM 公司开发了很多系列的 ARM 处理器


核, ARM6 核以及更早的系列已经很罕见了。

ARM7 ARM9 ARM11

Cortex-A Cortex-R Cortex-M

SecurCore
ARM 处理器结构综

ARM 系 微处理器核 特点

ARM7 ARM7TDMI :整数处理核  冯诺伊曼体系结构;
ARM7TDMI 处理器的可  ARMTDMI 是目前应用最广的微处理
综合版本; 器核
ARM720T :带 MMU 的处理  ARM720T 带有 MMU 和 8KB 的指令
器核心,支持操作系统; 数据混合 cache ;
ARM7EJ-S :带有 DSP 和  ARM7EJ- 执行 ARMv5TEJ 指令, 5 级
Jazelle TM 技术,能够实 流水线,提供 Java 加速指令,没有存储
现 Java 加速功能 器保护。

ARM9 ARM920T :带有独立的  基于 ARM9TDMI ,带 16 位的 Thumb


16KB 数据和指令 指令集,增强代码密度最多到 35% ;
Cache ;  在 0.13µm 工艺下最高性能可达到
ARM22T :带有独立的 8 位 300MIPS ( Dhrystone 2.1 测试标准);
KB 数据和指令 Cache ;  集成了数据和指令 Chche ;
ARM940T– 包括更小数据和  32 位 AMBA 总线接口的 MMU 支持;
指令 Cache 和一个 MPU  可在 0.18µm 、 0.15µm 和 0.13µm 工
艺的硅芯片上实现。
ARM 处理器结构综

ARM9E ARM926EJ-S : Jazelle 技术,有 ARM9E 是针对微控制器、 DSP 和 Java 的
MMU ,可配置的数据和指令 单处理器解决方案;
Cache,TCM 接口; ARM Jazelle  技术提供 8 倍的 Java 加速性
ARM946E-S :可配置的数据和指 能 (ARM926EJ-S) ;
令 Cache 及 TCM; 5- 级整数流水线;
ARM966E-S :针对要求高性能和 在 0.13µm 工艺下最高性能可达到 300MIPS
低功耗的可预测的指令执行时间 ( Dhrystone 2.1 测试标准);
的硬实时应用设计 可选择的 向量浮点单元 VFP9 协处理器指
ARM968E-S :最小、功耗最小的 令优秀浮点性能,对于 3D 图形加速和实时控
  ARM9E 系列处理器,针对嵌入 制可达到  215MFLOPS 。
式实时应用设计; 高性能的 AHB 总线,带 MMU
可在 0.18µm, 0.15µm, 0.13µm 工艺的硅芯片
上实现。
ARM10E ARM1020E :带 DSP 指令集,在 带分支预测的 6 级整数流水线;
片调试功能,独立的 32KB 数据 在 0.13µm 工艺下最高性能可达到 430MIPS
和指令 Cache , MMU 支持; ( Dhrystone 2.1 测试标准);
ARM1022E :与 ARM1020E 相 对于 3D 图形运算和实时控制采用 VFP 协处
同,只是独立的数据和指令 理器,浮点运算性能最高可达 650MFLOPS ;
Cache 变为 16KB ; 双 64 位 AMBA 总线接口和 64 位内部总路
ARM1026EJ-S :同时具有 MPU 线接口;
和 MMU ,可综合版本; 优化的缓存结构提高了处理器访问低速存储
器的性能;
可在 0.18µm, 0.15µm, 0.13µm 工艺的硅芯片
上实现
ARM 处理器结构综

ARM11 ARM11 MPCore :可综合的多处 增强的 Thumb 、 Jazelle 、 DSP 扩展支持;
理器核, 1 至 4 个处理器可配置; 带片上和系统安全 TrustZone 技术支持 ;
ARM1136J(F)-S :可配置的数据 在 0.13µm 工艺下最高可达到 550MHz ;
和指令 Cache ,可提供 1.9 位的 MPCore 在 0.13µm 工艺下最高性能可达到
MPEG4 编码加速功能; 740MIPS ( Dhrystone 2.1 测试标准);
ARM1156T2(F)-S :带集成浮点协 支持多媒体指令 SIMD ;
处理器,带内存保护单元 MPU  ; 采用三种电源模式:全速 / 待命 / 休眠
ARM1176JZ(F)-S :带针对 CPU 集成 DMA 的 TCM
和系统安全架构扩展的 低功耗、高性能。
TrustZone 技术。

SecurCore SC100 :第一个 32 位安全处理器; SecurCore 是专门为智能卡、安全 IC 提供的


、 SC110 :在 SC100 上增加密钥 32 位安全处理器, 为电子商务、银行、网络、
协处理器; 移动多媒体、公共交通提供安全解决方案;
SC200 :带 Jazelle 技术的高级安 体积小、功耗低,代码压缩密度高;
全处理器; 为快速增长的 Java 卡平台提供 Java 加速功
SC210 :在 SC200 上增加密钥协 能;
处理器
ARM 处理器结构综

Cortex Cortex-A :面向应用的微处 2004 年发布,提供增强的媒体和数字处
理器,针对复杂操作系统和 理能力,增加了系统性能;
应用程序设计; 支持 ARM 、 Thumb 、 Thumb-2 指令
Cortex-R :针对实时系统的 集;
嵌入式处理器; Thumb-2 指令集提供了更高的代码存储
Cortex-M :针对成本敏感 密度,进一步降低成本;
应用优化的深度嵌入式处
理器;
Intel 系列 StrongARM : ARMv4 体 StrongARM 主要应用于手持设备和
系 PDA , 5 级流水线,具有独立的数据和指令
XScale : ARMv5TE 体系, Cache ,不支持 Thumb 指令集,目前已停
增加 MMX 指令 产;
XScale 是目前 Intel 公司主推的高性能
嵌入式处理器,分通用处理器、网络处理
器和 I/O 处理器三类。其中通用处理器有
PXA25x 、 PXA26x 、 PXA27x 三个系
列,被广泛应用于智能手机、 PDA 领域。
2.3 ARM 微处理器的寄存器结构

 ARM 处理器共有 37 个寄存器,其中

 31 个通用寄存器

 6 个状态寄存器
2.3.1 处理器的运行模式

ARM 体系结构支持 7 种处理器模式,分别为:。


用户模式
快中断模式
中断模式
管理模式
中止模式
未定义模式
系统模式

这样的好处是可以更好的支持操作系统并提高工作效率
处理器运行模式
处理器模式 说明 备注
用户
正常程序工作模式 不能直接切换到其它模式
(usr)
系统 与用户模式类似,但具有可以直接切换
用于支持操作系统的特权任务等
(sys) 到其它模式等特权

快中断
支持高速数据传输及通道处理 FIQ 异常响应时进入此模式
(fiq)
中断
用于通用中断处理 IRQ 异常响应时进入此模式
(irq)
管理
操作系统保护代码 系统复位和软件中断响应时进入此模式
(svc)

中止
用于支持虚拟内存和 / 或存储器保护 在 ARM7TDMI 没有大用处
(abt)

未定义
支持硬件协处理器的软件仿真 未定义指令异常响应时进入此模式
(und)
处理器运行模式
 特权模式

处理器模式 说明 备注
用户
正常程序工作模式 不能直接切换到其它模式
(usr)
系统
系统 (sys) 用于支持操作系统的特 与用户模式类似,但具有可以
(sys)
快中断 权任务等 直接切换到其它模式等特权
除用户模式外,其它模式均为特权模式。
快中断(fiq) 支持高速数据传输及通
(fiq) ARM 内部寄存器和一些片内外设在硬件设计上
道处理
FIQ 异常响应时进入此模式
中断 (irq)
中断

管理 IRQ 异常响应时进入此模式
允许(或者可选为只允许)特权模式下访问。
用于通用中断处理
(irq) (svc)
管理 特权模式可以自由的切换处理器模式,而用户模
系统复位和软件中断响应时进
中止 操作系统保护代码
(svc) (abt) 式不能直接切换到别的模式
入此模式 。
中止
未定义 用于支持虚拟内存和 / 或
在 ARM7TDMI 没有大用处
(abt) (und) 存储器保护
未定义 支持硬件协处理器的软 未定义指令异常响应时进入此
处理器运行模式
 异常模式

处理器模式 说明 备注
用户
正常程序工作模式 不能直接切换到其它模式
(usr)
系统 用于支持操作系统的特 与用户模式类似,但具有可以
(sys)
快中断
 这五种模式称为异常模式。
权任务等 直接切换到其它模式等特权
快中断(fiq)  除了可以通过程序切换进入外,也可以由
支持高速数据传输及通
FIQ 异常响应时进入此模式
(fiq)
中断 (irq) 道处理 特定的异常进入。
中断
管理
 当特定的异常出现时,处理器进入相应的模式
用于通用中断处理 IRQ 异常响应时进入此模式
(irq) (svc) 。
管理
中止  每种异常模式都有一些独立的寄存器,以避免
系统复位和软件中断响应时进
操作系统保护代码
(svc) (abt) 异常退出时用户模式的状态不可靠。
入此模式
中止
未定义 用于支持虚拟内存和 / 或
在 ARM7TDMI 没有大用处
(abt) (und) 存储器保护
未定义 支持硬件协处理器的软 未定义指令异常响应时进入此
处理器运行模式
 用户和系统模式

处理器模式 说明 备注
用户
用户 (usr)
正常程序工作模式 不能直接切换到其它模式
(usr)
系统  这两种模式都不能由异常进入
系统 (sys)  它们使用完全相同的寄存器组。
用于支持操作系统的特 与用户模式类似,但具有可以
(sys) 权任务等 直接切换到其它模式等特权
 系统模式是特权模式,不受用户模式的限制。
快中断  操作系统在该模式下访问用户模式的寄存器就
支持高速数据传输及通
FIQ 异常响应时进入此模式
(fiq) 道处理
比较方便,而且操作系统的一些特权任务可以
中断 使用这个模式访问一些受控的资源。
用于通用中断处理 IRQ 异常响应时进入此模式
(irq)
管理 系统复位和软件中断响应时进
操作系统保护代码
(svc) 入此模式
中止 用于支持虚拟内存和 / 或
在 ARM7TDMI 没有大用处
(abt) 存储器保护
未定义 支持硬件协处理器的软 未定义指令异常响应时进入此
2.3.2 处理器的工作状态
ARM920T 处理器内核使用 V4T 版本的 ARM 结构,
该结构包含 32 位 ARM 指令集和 16 位 Thumb 指令集。
因此 ARM9 处理器有两种处理器状态:

ARM 状态: 32 位,这种状态下执行的是字方式的 ARM


指令;
Thumb 状态: 16 位,这种状态下执行半字方式的 Thumb
指令。
注意:两个状态之间的切换并不影响处理器模式或寄存器内容

( 1 )进入 Thumb 状态
 当操作数寄存器的状态位(位 [0] )为 1 时,执行 BX 指令进入
Thumb 状态。
 如果处理器在 Thumb 状态进入异常,则当异常处理( IRQ 、 FIQ
、 Undef 、 Abort 和 SWI )返回时,自动转换到 Thumb 状态。

( 2 )进入 ARM 状态
 当操作数寄存器的状态位(位[ 0 ])为 0 时,执行 BX
指令
进入 ARM 状态。
 处理器进行异常处理

( IRQ 、 FIQ 、 Reset 、 Undef 、 Abort 和


SWI )。也可以进入 ARM 状态。
使用 BX 指令将 ARM 内核的操作状态在 ARM 状
态和 Thumb 状态之间进行切换,程序如下所示。

跳转地址标号
; 从 Arm 状态切换到 Thumb 状态
地址最低位
LDR R0,=Lable+1
为 1 ,表示
BX R0 切换到
Thumb 状态
; 从 Thumb 状态切换到 ARM 状态
LDR R0,=Lable 地址最低位为
0 ,表示切换
BX R0 到 ARM 状态
2.3.3 处理器的寄存器组织

 简介

在 ARM 处理器内部有 37 个用户可见的寄存器


在不同的工作模式和处理器状态下,程序员可
以访问的寄存器也不尽相同。
ARM 状态各模式下的寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
R4(v1) R4
R5(v2) R5
R6(v3) R6
通用寄
存器和 R7(v4) R7
程序计 R8(v5) R8 R8_fiq
数器
R9(SB,v6) R9 R9_fiq
R10(SL,v7) R10 R10_fiq
R11(FP,v8) R11 R11_fiq
R12(IP) R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
ARM 状态各模式下的寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0
R0(a1) R0
R1
R1(a2) R1
R2
R2(a3) R2
R3
R3(a4) R3
R4
R4(v1) R4
R5
R5(v2) R5
R6
R6(v3) R6
通用寄 所有的 37 个寄存器,分成两大类: R7
存器和 R7(v4) R8 R7 R8_fiq
程序计 31 个通用 32 位寄存器;
R8(v5) R8
R9 R8_fiq
R9_fiq
数器
R9(SB,v6)
6 个状态寄存器。 R9
R10 R9_fiq
R10_fiq
R10(SL,v7) R10
R11 R10_fiq
R11_fiq
R11(FP,v8) R11
R12 R11_fiq
R12_fiq
R12(IP) R13 R13_svcR12R13_abt R13_und R13_irq R12_fiq
R13_fiq
R13(SP) R13
R14 R13_svc
R14_svc R13_abt
R14_abt R13_und
R14_und R13_irq
R14_irq R13_fiq
R14_fiq
R14(LR) R14 R14_svc R14_abt
R15 R14_und R14_irq R14_fiq
R15(PC) R15
CPSR
状态寄 CPSR CPSR SPSR_und SPSR_irq SPSR_fiq
SPSR_abt SPSR_abt
存器
ARM 状态各模式下可以访问的寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
用户 系统 管理 中止 未定义 中断 快中断
R0
R0(a1) R0
R1
R1(a2) R1
R2
R2(a3) R2
R3
R3(a4) R3
R4
R4(v1) R4
R5
R5(v2) R5
R6
R6(v3) R6
R7
通用寄
存器和 R7(v4) R8 R7 R8_fiq
程序计 R8(v5) R8 R8_fiq
R9 R9_fiq
数器
R9(SB,v6) R9
R10 R9_fiq
R10_fiq
R10(SL,v7) R10
R11 R10_fiq
R11_fiq
R11(FP,v8) R11
R12 R11_fiq
R12_fiq
R12(IP) R13 R13_svcR12R13_abt R13_und R13_irq R12_fiq
R13_fiq
R13(SP) R13
R14 R13_svc
R14_svc R13_abt
R14_abt R13_und
R14_und R13_irq
R14_irq R13_fiq
R14_fiq
R14(LR) R14 R14_svc R14_abt
R15 R14_und R14_irq R14_fiq
R15(PC) R15
CPSR
状态寄 CPSR 无 CPSR SPSR_und SPSR_irq SPSR_fiq
SPSR_abt SPSR_abt
存器
一般的通用寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0
R0(a1) R0
R1
R1(a2) R1
R2
R2(a3) R2
R3
R3(a4) R3
R4
R4(v1) 在汇编语言中寄存器 R13 R4
R0R5

R5(v2) 为保存数据或地址值的通用寄存器。
R5
R6

通用寄
R6(v3) 它们是完全通用的寄存器,不会被
R6
R7
存器和 R7(v4) 体系结构作为特殊用途,并且可用
R8 R7 R8_fiq
程序计
数器
R8(v5) 于任何使用通用寄存器的指令。
R8
R9 R8_fiq
R9_fiq
R9(SB,v6) R9
R10 R9_fiq
R10_fiq
R10(SL,v7) R10
R11 R10_fiq
R11_fiq
R11(FP,v8) R11
R12 R11_fiq
R12_fiq
R12(IP) R13 R13_svcR12R13_abt R13_und R13_irq R12_fiq
R13_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
一般的通用寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0
R0(a1) R0
R1
R1(a2) R1
R2
其中 R2(a3)
R0 ~ R7 为未分组的寄存器, R2
R3
也就是说对于任何处理器模式,这些寄
R3(a4) R3
R4
存器都对应于相同的
R4(v1) 32 位物理寄存器 R4
R5
。 R5(v2) R5
R6
R6(v3) R6
R7
通用寄
存器和 R7(v4) R8 R7 R8_fiq
程序计 R8(v5) R8 R8_fiq
R9 R9_fiq
数器
R9(SB,v6) R9
R10 R9_fiq
R10_fiq
R10(SL,v7) R10
R11 R10_fiq
R11_fiq
R11(FP,v8) R11
R12 R11_fiq
R12_fiq
R12(IP) R13 R13_svcR12R13_abt R13_und R13_irq R12_fiq
R13_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
一般的通用寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
寄存器 R8 ~ R14 为分组寄存
R1(a2) R1
器。它们所对应的物理寄存器取
R2(a3) R2
决于当前的处理器模式,几乎所
R3(a4) R3
有允许使用通用寄存器的指令都
R4(v1) R4
允许使用分组寄存器
R5(v2) R5
R6(v3) R6
通用寄
存器和 R7(v4) R8 R7 R8_fiq
程序计 R8(v5) R8 R8_fiq
R9 R9_fiq
数器
R9(SB,v6) R9
R10 R9_fiq
R10_fiq
R10(SL,v7) R10
R11 R10_fiq
R11_fiq
R11(FP,v8) R11
R12 R11_fiq
R12_fiq
R12(IP) R13 R13_svcR12R13_abt R13_und R13_irq R12_fiq
R13_fiq
R13(SP) R13
R14 R13_svc
R14_svc R13_abt
R14_abt R13_und
R14_und R13_irq
R14_irq R13_fiq
R14_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
一般的通用寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) 寄存器 R8 ~ R12 有两个分组的物理寄存
R2
R3(a4) 器。一个用于除 FIQ 模式之外的所有寄存器
R3
R4(v1) 模式,另一个用于 FIQ 模式。这样在发生
R4
R5(v2) FIQ 中断后,可以加速 FIQ R5的处理速度。
R6(v3) R6
通用寄
存器和 R7(v4) R8 R7 R8_fiq
程序计 R8(v5) R8 R8_fiq
R9 R9_fiq
数器
R9(SB,v6) R9
R10 R9_fiq
R10_fiq
R10(SL,v7) R10
R11 R10_fiq
R11_fiq
R11(FP,v8) R11
R12 R11_fiq
R12_fiq
R12(IP) R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
一般的通用寄存器
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
R4(v1) R4
R5(v2) R5
R6(v3) R6
通用寄
存器和 R7(v4) R7
程序计 寄存器 R13 、 R14 分别有 6 个分组的物理寄存器。
R8(v5) R8 R8_fiq
数器 一个用于用户和系统模式,其余 5 个分别用于 5 种异常
R9(SB,v6) R9 R9_fiq
模式。
R10(SL,v7) R10 R10_fiq
R11(FP,v8) R11 R11_fiq
R12(IP) R13 R13_svcR12R13_abt R13_und R13_irq R12_fiq
R13_fiq
R13(SP) R13
R14 R13_svc
R14_svc R13_abt
R14_abt R13_und
R14_und R13_irq
R14_irq R13_fiq
R14_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
堆栈指针寄存器 R13 ( SP )
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
R4(v1) R4
R5(v2) R5

通用寄
R6(v3) 寄存器 R13 常作为堆栈指针(
R6 SP )
存器和 R7(v4) R7
程序计 R8(v5) R8 R8_fiq
数器
 ARM 指令集当中,习惯上使用 R13 。
R9(SB,v6) R9 R9_fiq
 Thumb 指令集中必须使用 R13 。
R10(SL,v7) R10 R10_fiq
R11(FP,v8) R11 R11_fiq
R12(IP) R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
链接寄存器 R14 ( LR )
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
R4(v1) R4
R5(v2) R5
R14 为链接寄存器( LR ),在结构上有两个特殊功能:
R6(v3) R6
通用寄
存器和 R7(v4) R7
程序计
 在每种模式下,模式自身的 R14 用于保存子程序返回地址;
R8(v5) R8 R8_fiq
数器  当发生异常时, R14 保存对应的异常返回地址(有些异常有一
R9(SB,v6) R9 R9_fiq
个小的固定偏移量)。
R10(SL,v7) R10 R10_fiq
R11(FP,v8) R11 R11_fiq
R12(IP) R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
 R14 寄存器与子程序调用

操作流程
1. 程序 A 执行过程中调用程序
B2.;
程序跳转至标号 Lable ,
执行程序 B 。同时硬件 程序 A 程序 B
将“ BL Lable” 指令的下 Lable ???
一条指令所在地址存入 R14
; BL Lable
3. 程序 B 执行最后,将 R14
寄存器的内容放入 PC ,返回 地址 A ???
MOV PC,LR
程序 A ;
地址 A)
R14(R14
同一模式下子程序嵌套时 R14 有可能发生覆盖错误。

例: IRQ 模式下程序 A 调用程序 B ,程序 B 又调用了


程序 C ;则后一次的调用指令 BL 将返回地址保存到
R14_IRQ 中时,就将前一次保存到 R14_IRQ 中的返回地址
覆盖了。导致 C 可以正确返回到 B ,但 B 不能正确返回到
A 了。

可以对 R14 进行入栈保存或转存避免此类错误。


 R14 寄存器与异常发生

异常发生时,程序要跳转至异常服务程序,
对返回地址的处理与子程序调用类似,都是由硬件完成的。
区别在于有些异常有一个小常量的偏移。
 R14 寄存器注意要点

当发生异常嵌套时,这些异常之间可能会发生冲突。例如:
如果用户在用户模式下执行程序时发生了 IRQ 中断,用户模式
寄存器不会被破坏。
但是如果允许在 IRQ 模式下的中断处理程序重新使能 IRQ 中断
,并且发生了嵌套的 IRQ 中断时,外部中断处理程序保存在 R14_irq
中的任何值都将被嵌套中断的返回地址所覆盖。
 R14 寄存器注意要点

用户模式下的程序 IRQ 模式下的程序 A


3. 发生
2. IRQ 服务程
IRQ 中 a
断,硬件将某
序 A 执行完毕
个地址存入
,将 R14_irq 寄 A
1. 执行用户模
存器的内容减
IRQ 模式下的 B
...
式下的程序;
去某个常量后
R14_irq 寄存器 地址 X
,用户模式下
存入 PC ,返回 A
的 R14 没有被
之前被中断的 return
破坏;
程序;
R14 地址 A
R14_irq

未被破坏
 R14 寄存器注意要点

用户模式下的程序 IRQ 模式下的程序 A IRQ 模式下的程序 B


6. 发生
2.
3. 在程序
IRQ 服务程
IRQB 中
返 a a
如果在 IRQ
硬件将返回
4.解决办法是确保
5. R14 的
断,硬件将某

回到程序A 执行完毕 A ,
处理程序中打
地址保存在
对应版本在发生中断嵌套
个地址存入
,将
然后在返回到R14_irq 寄 A A

R14_irq
IRQ 中断,
寄存器
时不再保存任何有意义的
1. 执行用户模
存器的内容减
用户模式下被
IRQ 模式下的 B B
并且再次发生
中,原来保存
值(将 R14 入栈),或者 ... ...
式下的程序;
去某个常量后
中断的程序时
R14_irq 寄存器 地址 地址
的返回地址将
IRQ 中断,或
切换到其它处理器模式下
X X
,用户模式下
存入
,发生错误,PC ,返回 A B
者调用子程序
被覆盖,造成
。将不能正确返
的 R14 没有被
之前被中断的 return return

错误;
破坏;
程序;
回;
R14 R14_irq
地址 A B

未被破坏 被破坏
程序计数器 R15 ( PC )
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
R4(v1) R4
R5(v2) R5
R6(v3) 寄存器 R15 为程序计数器( R6 PC ),它指向正在取
通用寄
存器和 R7(v4) 指的地址。 R7
程序计 R8(v5) 可以认为它是一个通用寄存器,但是对于它的使
R8 R8_fiq
数器
R9(SB,v6) 用有许多与指令相关的限制或特殊情况。
R9 R9_fiq
R10(SL,v7) 如果 R15 使用的方式超出了这些限制,那么结
R10 R10_fiq
R11(FP,v8) 果将是不可预测的。R11 R11_fiq
R12(IP) R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
 读 R15 的限制
正常操作时,从 R15 读取的值是处理器正在取指
的地址,即当前正在执行指令的地址加上 8 个字节
(两条 ARM 指令的长度)。
由于 ARM 指令总是以字为单位,所以 R15 寄存器
的最低两位总是为 0 。
地址 程序代码 流水线状态
PC-8 LDR R0,PC 正在执行
PC-4 ??? 正在译码
PC ??? 正在取指
 写 R15 的限制

正常操作时,写入 R15 的值被当作一个指令地址,


程序从这个地址处继续执行(相当于执行一次无条件跳转)。
 写 R15 的限制

由于 ARM 指令要求字对齐,因此写入 R15 的值最低两位


通常为 0b00 。具体的规则取决于内核结构的版本:
在 ARM 结构 V3 版及以下版本中,写入 R15 的值的最
低两位被忽略,因此跳转地址由指令的实际目标地址(写
入 R15 的值)和 0xFFFFFFFC 相与得到;
在 ARM 结构 V4 版及以上版本中,写入 R15 的值的最
低两位为 0 ,如果不是,结果将不可预测。
程序状态寄存器 CPSR
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断

R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
R4(v1) R4
R5(v2) R5
R6(v3) R6
通用寄
存器和 R7(v4) R7
 CPSR 为当前程序状态寄存器,
程序计 R8(v5) R8 R8_fiq
数器  SPSR 为程序状态保存寄存器(异常模式下)
R9(SB,v6) R9 R9_fiq
R10(SL,v7) R10 R10_fiq
 因为异常事件而进入异常时它保存 CPSR 的当前
R11(FP,v8) R11 R11_fiq
值,异常退出时可通过它恢复 CPSR 。
R12(IP) R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_irq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_irq R14_fiq
R15(PC) R15
状态寄 CPSR CPSR
存器
程序状态寄存器
 简介

每个异常模式还带有一个程序状态保存寄存器
( SPSR ),它用于保存在异常事件发生之前的
CPSR 。 CPSR 和 SPSR 通过特殊指令进行访问。
注意:如果通过程序修改 CPSR 寄存器中的模式位
进入异常模式,那么硬件将不会把 CPSR 保存至
SPSR 中。
程序状态寄存器
 简介
ARM 内核包含 1 个 CPSR 和 5 个供异常处理程序使用的 SPSR 。
CPSR 反映了当前处理器的状态,其包含:

 4 个条件代码标志(负 (N) 、零 (Z) 、进位 (C) 和溢出 (V) );


 2 个中断禁止位,分别控制一种类型的中断;
 5 个对当前处理器模式进行编码的位;
 1 个用于指示当前执行指令 (ARM 还是 Thumb) 的 T 位。
程序状态寄存器
 简介
CPSR 寄存器的格式
条件代码标志 保留 控制位

31 30 29 28 27 26 8 7 6 5 4 3 2 1 0
N Z C V — — ... — I F T M4 M3 M2 M1 M0
溢出标志
进位或借位扩展 模式位
零 状态位
负或小于 FIQ 禁止
IRQ 禁止
程序状态寄存器
 条件代码标志

大多数“数值处理指令”可以选择是否影响条件代码标志位。
通常如果指令带 S 后缀,则该指令的执行会影响条件代码标志
;但有一些指令的执行总是会影响条件代码标志。
N 、 Z 、 C 和 V 位都是条件代码标志。通过算术操作、逻辑
操作、 MSR 或者 LDM 指令可以对这些位进行设置。
所有 ARM 指令都可按条件来执行,而 Thumb 指令中只有分
支指令可按条件执行。
程序状态寄存器
 条件代码标志

各标志位的含义如下:
N 运算结果的最高位反映在该标志位。对于有符
号二进制补码,结果为负数时 N=1 ,结果为正数或
零时 N=0 ;
Z 指令结果为 0 时 Z=1 (通常表示比较结果“相
等”),否则 Z=0 ;
程序状态寄存器
 条件代码标志
各标志位的含义如下:
C 当进行加法运算 (包括 CMN 指令 ),并且最
高位产生进位时 ,C=1 ,否则 C=0 。
当进行减法运算 (包括 CMP 指令 ),并且最
高位产生借位时 ,C=0 ,否则 C=1 。
对于结合移位操作的非加法 /减法指令, C 为
从最高位最后移出的值,其它指令 C 通常不变;
V 当进行加法 /减法运算,并且发生有符号溢出时
V=1 ,否则 V=0 ,其它指令 V 通常不变。
程序状态寄存器
 控制位

CPSR 的最低 8 位为控制位,当发生异常时,这


些位被硬件改变。当处理器处于一个特权模式时,
可用软件操作这些位。
它们分别是:
中断禁止位 I 、 F ;

T 位;

模式位 M4-M0 。
程序状态寄存器
 控制位

中断禁止位包括 I 和 F 位:
当 I=1 时, IRQ 中断被禁止;

当 F=1 时, FIQ 中断被禁止。

T 位反映了正在操作的状态:
当 T=1 时, 处理器正在 Thumb 状态下运行;

当 T=0 时,处理器正在 ARM 状态下运行。


程序状态寄存器
 控制位

模式位包括 M4 、 M3 、 M2 、 M1 和 M0 ,这
些位决定处理器的操作模式。
注意:不是所有模式位的组合都定义了有效的处理
器模式,如果使用了错误的设置,将引起一个无法
恢复的错误。
CPSR 模式位设置表

M[4:0] 模式 可见的 Thumb 状态寄存器 可见的 ARM 状态寄存器


10000 用户 R0 ~ R7,SP,LR,PC,CPSR R0 ~ R14,PC, CPSR
R0 ~ R0 ~ R7,R8_fiq ~
10001 快中断 R7,SP_fiq,LR_fiq,PC,CPSR, R14_fiq,PC,
SPSR_fiq CPSR, SPSR_fiq
R0 ~ R0 ~
10010 中断 R7,SP_irq,LR_irq,PC,CPSR, R12,R13_irq,R14_irq,PC,
SPSR_fiq CPSR, SPSR_irq
R0 ~ R0 ~
10011 管理 R7,SP_svc,LR_svc,PC,CPSR, R12,R13_svc,R14_svc,
SPSR_svc PC,CPSR, SPSR_svc
R0 ~ R0 ~
10111 中止 R7,SP_abt,LR_abt,PC,CPSR, R12,R13_abt,R14_abt,PC,
SPSR_abt CPSR, SPSR_abt
R0 ~ R0 ~ R12,R13_und,R14_und,
11011 未定义 R7,SP_und,LR_und,PC,CPSR,
SPSR_und PC,CPSR,SPSR_und

11111 系统 R0 ~ R7,SP,LR,PC,CPSR R0 ~ R14,PC, CPSR


程序状态寄存器
 保留位

CPSR 中的保留位被保留将来使用。
为了提高程序的可移植性,当改变 CPSR 标志和
控制位时,请不要改变这些保留位。
另外,请确保您程序的运行不受保留位的值影响
,因为将来的处理器可能会将这些位设置为 1 或者 0 。
 2.3.4 Thumb 状态寄存器

Thumb 状态寄存器集是 ARM 状态集的子集,程序员可以


直接访问的寄存器为:
8 个通用寄存器 R0 ~ R7 ;

程序计数器( PC );

堆栈指针( SP );

链接寄存器( LR );

有条件访问程序状态寄存器( CPSR )。
Thumb 状态各模式下的寄存器
寄存器 寄存器在汇编 各模式下实际访问的寄存器
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
通用寄 R4(v1) R4
存器和
R5(v2) R5
程序计
数器 R6(v3) R6
R7(v4,wr) R7
SP R13 R13_svc R13_abt R13_und R13_irq R13_fiq
LR R14 R14_svc R14_abt R14_und R14_irq R14_fiq
PC R15

状态寄
CPSR CPSR
存器

注意:括号内为 ATPCS 中寄存器的命名,可以使用 RN 汇编伪指令将寄存


器定义多个名字。其中 ADS1.2 的汇编程序直接支持这些名称,但注意 a
1 ~ a4 , v1 ~ v4 必须用小写。
Thumb 状态下的通用寄存器
寄存器 寄存器在汇编 各模式下实际访问的寄存器
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
通用寄 R4(v1) R4
存器和
R5(v2) R5
程序计
数器 R6(v3) R6
R7(v4,wr) R7
SP R13 R13_svc R13_abt R13_und R13_irq R13_fiq
LR R14 R14_svc R14_abt R14_und R14_irq R14_fiq
在汇编语言中寄存器 R0 ~ R7 为保存数据或地址值
PC R15
的通用寄存器。对于任何处理器模式,它们中的每一个
状态寄
CPSR 都对应于相同的 32 位物理寄存器。
CPSR
存器
它们是完全通用的寄存器,不会被体系结构作为特
殊的用途,并且可用于任何使用通用寄存器的指令。
Thumb 状态下的堆栈指针寄存器
( SP )
各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
通用寄 R4(v1) R4
存器和
R5(v2) R5
程序计
数器 R6(v3) R6
R7(v4,wr) R7
SP R13 R13_svc R13_abt R13_und R13_irq R13_fiq
LR R14 R14_svc R14_abt R14_und R14_irq R14_fiq
PC R15
堆栈指针 SP 对应 ARM 状态的寄存器 R13 。
状态寄
存器
CPSR 每个异常模式都有其自身的 SP 分组版本, SP 通常指向
CPSR
各异常模式所专用的堆栈。
注意:在发生异常时,处理器自动进入 ARM 状态

Thumb 状态下的链接寄存器
LR )
R14 ( 各模式下实际访问的寄存器
寄存器 寄存器在汇编
类别 中的名称 用户 系统 管理 中止 未定义 中断 快中断
R0(a1) R0
R1(a2) R1
R2(a3) R2
R3(a4) R3
通用寄 R4(v1) 链接寄存器 LR 对应 ARMR4状态寄存器 R14 ,在结构
存器和
R5(v2) 上有两个特殊功能。 R5
程序计
数器 R6(v3) 注意:在发生异常时,处理器自动进入
R6 ARM 状态
R7(v4,wr) 。 R7
SP R13 R13_svc R13_abt R13_und R13_irq R13_fiq
LR R14 R14_svc R14_abt R14_und R14_irq R14_fiq
PC R15

状态寄
CPSR CPSR
存器
 ARM 状态和 Thumb 状态之间寄存器的关系
Thumb 状态寄存器与 ARM 状态寄存器有如下的关系

Thumb 状态 R0 ~ R7 与 ARM 状态 R0 ~ R7 相同

Thumb 状态 CPSR 与 ARM 状态 CPSR 相同;

Thumb 状态 SP 映射到 ARM 状态 R13 ;

Thumb 状态 LR 映射到 ARM 状态 R14 ;

Thumb 状态 PC 映射到 ARM 状态 PC ( R15 )。


Thumb 状态寄存器在 Arm 状态寄存器上的映射
Thumb 状态 AR M 状态
R0 R0
R1 R0
R1
R2 R1
R2
R3 R2
R3
R4 R3
R4
R5 R4
R5
低寄存器
R6 R5
R6
R7 R6
R7
R7
R8
R8
R9
R9
R10
R10
R11
R11
R12
堆栈指针(SP) R12 高寄存器
堆栈指针(R13)
连接寄存器(LR) 堆栈指针 (R13)
连接寄存器(R14)
程序计数器(PC) 连接寄存器 (R14)
程序计数器(R15)
程序计数器 (R15)
当前程序状态寄存器 当前程序状态寄存器
(C P SR ) (C P SR )

被保存程序状态寄存器 被保存程序状态寄存器
( SP SR ) (SP SR )
 在 Thumb 状态中访问高寄存器

在 Thumb 状态中,高寄存器( R8 ~ R15 )不是


标准寄存器集的一部分。汇编语言程序员对它们的访
问受到限制,但可以将它们用于快速暂存。
可以使用 MOV 、 CMP 和 ADD 指令对高寄存
器操作。
2.4 ARM 微处理器的异常处理
 简介

在一个正常的程序流程执行过程中,由内部或外部源产生
的一个事件使正常的程序产生暂时的停止时,称为异常。
处理异常之前,当前处理器的状态必须保留,异常处理
完成之后,恢复保留的当前处理器状态,继续执行当前程序

多个异常同时发生时,处理器会按固定优先级进行处理

2.4.1 ARM 体系结构的异常类型
进入 进入

地址(异常向 时I 时F
异常类型 模式 先
量) 的状 的状

态 态
1 复位 管理 1 0x0000 0000 禁止 禁止
2 未定义指令 未定义 6 0x0000 0004 I F
3 软件中断 管理 6 0x0000 0008 禁止 F
中止(预
4 中止 5 0x0000 000C I F
取)
中止(数
5 中止 2 0x0000 0010 I F
据)
保留 保留 0x0000 0014 — —
6 IRQ IRQ 4 0x0000 0018 禁止 F
7 FIQ FIQ 3 0x0000 001C 禁止 禁止
注:表中的 I 和 F 表示不对该位有影响,保留原来的指。
2.4.2 异常类型的含义

 ( 1 )复位

当内核 nRESET 信号被拉低时(一般外部复位


引脚电平的变化和芯片的其它复位源会改变这个内
核信号), ARM 处理器立刻停止执行当前指令。

复位后, ARM 处理器在禁止中断的管理模式下,程


序跳转到复位异常处理程序处执行(从地址 0x00000000
或 0xFFFF0000 开始执行指令)。

在复位后,除 PC 和 CPSR 之外的所有寄存器的值都不确定。


当 nRESET 信号再次变为高电平时, ARM 处理器执行下列操作:

1. 强制 M[4:0] 变为 b10011 (管理模式);

2. 置位 CPSR 中的 I 和 F 位(禁止 I 和 F );

3. 清零 CPSR 中的 T 位( ARM 状态);

4. 强制 PC 从地址 0x00 开始对下一条指令进行取指;

5. 返回到 ARM 状态并恢复执行 。


 ( 2 )未定义的指令

当 ARM 处理器遇到一条自己和系统内任何协处理
器都无法处理的指令时,内核执行未定义指令陷阱。
软件可使用这一机制通过模拟未定义的协处理器
指令来扩展 ARM 指令集。

在模拟处理了失败的指令后,陷阱程序执行下面的指令:
MOVS PC, R14_und
恢复 PC 和 CPSR 并返回到未定义指令之后的指令。
注: MOVS 特殊指令,给 PC 赋值的同时将 SPSR 的值给 CPSR
 ( 3 )软件中断指令

执行指令 SWI 产生。可以使用该机制实现用户模


式下的程序调用特权操作指令,实现系统功能调用。
可以进入管理模式,通常用于请求特定的管理(操作
系统)函数。 SWI 处理程序通过执行下面的指令返
回:
MOVS PC , R14_svc

这个动作恢复了 PC 和 CPSR 并返回到 SWI 之后


的指令。 SWI 处理程序读取操作码以提取 SWI 函数
编号。
 中止
中止发生在对存储器的访问不能完成时,中止包含两种类
型:预取中止和数据中止。
( 4 )预取中止:发生在指令预取过程中。若处理器
预取指令的地址不存在,或该地址不允许当前指令访问,
存储器会向处理器发出存储器中止( Abort )信号,但当
预取的指令被执行时,才会产生指令预取中止异常。
在处理中止的原因之后,不管处于哪种处理器操作状态
,处理程序都会执行下面的指令恢复 PC 和 CPSR 并重试
被中止的指令:
SUBS PC, R14_abt, #4
 ( 5 )数据中止:发生在对数据访问时。 若处理器数据访
问指令的地址不存在,或该地址不允许当前指令访问时,产
生数据中止异常。存储器系统发出存储器中止信号。响应数
据访问(加载或存储)激活中止,标记数据为无效。在后面
的任何指令或异常改变 CPU 状态之前,数据中止异常发生

在修复产生中止的原因后,不管处于哪种处理器操作状
态,处理程序都必须执行下面的返回指令 :
SUBS PC,R14_abt,#8
 ( 6 )外部中断 IRQ 请求

当 nIRQ 输入端低电平有效,且 CPSR 中的 I 位为 0


时产生 IRQ 中断。
IRQ 的优先级低于 FIQ 。对于 FIQ 序列它是被屏蔽
的。任何时候在一个特权模式下,都可通过置位 CPSR
中的 I 位来禁止 IRQ 。
不管异常入口是来自 ARM 状态还是 Thumb 状
态, FIQ 处理程序都会通过执行下面的指令从中断返回

SUBS PC, R14_fiq , #4
 ( 7 )快速中断( FIQ )请求

当 nFIQ 中断请求引脚有效,且 CPSR 中的 F 位


为 0 时产生 FIQ 中断。
FIQ 适用于对一个突发事件的快速响应,这得益于
在 ARM 状态中,快中断模式有 8 个专用的寄存器可用
来满足寄存器保护的需要(可以加速上下文切换的速
度)。
FIQ 处理程序通过执行下面的指令从中断返回:
SUBS PC , R14_fiq, #4

在一个特权模式中,可以通过置位 CPSR 中的 F 位
来禁止 FIQ 异常。
2.4.3 异常的响应过程
 进入异常

在异常发生后, ARM 内核会作以下工作:

1.在相应的 LR 中保存下一条指令的地址;
2.将 CPSR 复制到相应的 SPSR 中;
3. 将 CPSR 模式位强制设置为与异常类型相对应的值

4. 强制 PC 从相关的异常向量处取指。
图示进入异常过程

2. 用户程序运行时发生 系统模式 IRQ 模式


IRQ 中断,硬件完成以下
1. 程序在系统模式下运行 程序 A IRQ 服务程序
动作:
用户程序,假定当前处理
器状态为 Thumb 状态、允
将 CPSR 寄存器内容存入

p
m
Ju
许 IRQ
IRQ 模式的中断;
SPSR 寄存器 程

置位 I位(禁止 IRQ 中断)
清零 T 位(进入 ARM 状
态)
LR LR_sys BackAddr
LR_irq
设置 MOD 位,切换处理器
寄 PC JumpAddr
将下一条指令的地址存入
模式至 IRQ 模式 存 N Z C V . . . I F T MOD
器 CPSR ? ? ? ? . . . 10 ? 01 IRQ
IRQ 模式的 LR 寄存器 SYS
组 SPSR SPSR_irq
????. . .0?1SYS
将跳转地址存入 PC ,实
“?” 表示对该位不关心
现跳转
ARM 内核在中断异常时置位中断禁止标志,这
样可以防止不受控制的异常嵌套。

注:异常总是在 ARM 状态中进行处理。当处理器


处于 Thumb 状态时发生了异常,在异常向量地址
装入 PC 时,会自动切换到 ARM 状态。
 退出异常

当异常结束时,异常处理程序必须:
1. 将 LR 中的值减去偏移量后存入 PC ,偏移量根据异
常的类型而有所不同;
2. 将 SPSR 的值复制回 CPSR ;
3. 清零在入口置位的中断禁止标志。

注:恢复 CPSR 的动作会将 T 、 F 和 I 位自动恢复为


异常发生前的值。
图示退出异常过程

在异常处理结束后,异常 系统模式 IRQ 模式


处理程序完成以下动作: 程序 A IRQ 服务程序

将 SPSR 寄存器的值复制
回 CPSR 寄存器; 程
将 LR 寄存的值减去一个 序

Ju
常量后复制到 PC 寄存器

m
p
,跳转到被中断的用户程 return
序。
LR LR_sys BackAddr
LR_irq
寄 PC BackAddr-4
JumpAddr
存 N Z C V . . . I F T MOD
器 CPSR ? ? ? ? . . . 01 ? 10 IRQ
SYS
组 SPSR SPSR_irq
????. . .0?1SYS

“?” 表示对该位不关心
当多个异常同时发生时,一个固定的优先级系统
决定它们被处理的顺序:

异常类型 优先级
复位 1 (最高优先级)
数据中止 2 优

FIQ 3 级

IRQ 4 低

预取中止 5
未定义指令 6 (最低优先级)
SWI 6 (最低优先级)
注意:
未定义的指令和 SWI 异常互斥。因为同一条指令
不能既是未定义的,又能产生有效的软件中断;
当 FIQ 使能,并且 FIQ 和数据中止异常同时发生
时, ARM 内核首先进入数据中止处理程序,然后
立即跳转到 FIQ 向量。在 FIQ 处理结束后返回到
数据中止处理程序。
数据中止的优先级必须高于 FIQ 以确保数据转移
错误不会被漏过。
异常入口 /出口汇总
之前的状态
异常或入口 返回指令 Thumb 备注
ARM R14_x
R14_x
SWI MOVS PC,R14_svc PC+4 PC+2 PC 为 BL , SWI ,
未定义的指令 MOVS PC,R14_und PC+4 PC+2 未定义的指令取指或
SUBS 预取指中止指令的地
预取指中止 PC+4 PC+4 址
PC,R14_abt,#4
快中断 SUBS PC,R14_fiq,#4 PC+4 PC+4 PC 为由于 FIQ 或 IRQ
SUBS 占先而没有被执行的
中断 PC+4 PC+4 指令的地址
PC,R14_irq,#4
PC 为产生数据中止的
SUBS
数据中止 PC+8 PC+8 装载或保存指令的地
PC,R14_abt,#8
址。
复位时保存在
复位 无 — — R14_svc 中的值不可
注意:“ MOVS PC , R14_svc” 是指在管理模式执行 MOVS预知。
PC , R14 指令

“MOVS PC , R14_und” 、“ SUBS PC,R14_abt , #4” 等指令也是类
似的。
 异常的入口和出口处理

如果异常处理程序已经把返回地址拷贝到堆栈
,那么可以使用一条多寄存器传送指令来恢复用户
寄存器并实现返回。

中断处理代码的开始部分和退出部分

SUB LR,LR,#4 ; 计算返回地址


STMFD SP!,{R0-R3,LR} ; 保存使用到的寄存器
. . .
LDMFD SP!,{R0-R3,PC}^ ; 中断返回
注意:
中断返回指令的寄存器列表(其中必须包括 PC )后的
如果异常处理程序已经把返回地址拷贝到堆栈
“^” 符号表示这是一条特殊形式的指令。
,那么可以使用一条多寄存器传送指令来恢复用户
这条指令在从存储器中装载
寄存器并实现返回。 PC 的同时( PC 是最后恢复
的), CPSR 也得到恢复。
中断处理代码的开始部分和退出部分
这里使用的堆栈指针 SP ( R13 )是属于对应异常模式的
堆栈指针。这个堆栈指针应必须在系统启动时初始化。

SUB LR,LR,#4 ; 计算返回地址


STMFD SP!,{R0-R3,LR} ; 保存使用到的寄存

. . .
LDMFD SP!,{R0-R3,PC}^ ; 中断返回
2.4.4 应用程序中的异常处理

 在应用程序的设计中,异常处理采用的方式是
在异常向量表中的特定位置放置一条跳转指令
,跳转到异常处理程序。

 当 ARM 处理器发生异常时,程序计数器 PC 会
被强制设置为对应的异常向量,从而跳转到异
常处理程序,当异常处理完成以后,返回到主
程序继续执行。
2.4.4 应用程序中的异常处理

中断与异常的区别
中断: CPU 对系统发生的某个事件作出的一种反
应, CPU 会暂停正在执行的程序,保留现场后自动转去
执行相应的处理程序,处理完该事件后再返回断点,继续
执行被“中断”的程序。通常与当前运行的进程无关,属
于正常现象。中断可以被屏蔽,在屏蔽解除至后,中断可
以继续得到响应和处理。

异常:是由指令执行期间所检测到的不正常的或非法的
条件引起的,与正在执行的指令有直接的联系。异常通常
不能被屏蔽,以便及时得到响应和处理。
2.5 ARM 的存储器结构
 地址空间

ARM 结构使用单个平面的 232=4G 个 8 位字节地


址空间。字节地址按照无符号数排列,从 0 到 232
- 1 。地址空间可以看作是包含 230 个 32 位字 ,
或 231 个 16 位半字。如果地址向上或向下溢出地址
空间,通常会发生翻转。
注意:如果在取指操作时地址发生溢出,只要没有
执行预取的无效指令,就不会导致异常。
2.5 ARM 的存储器结构
 地址空间

跳转目标的计算方法:
(当前指令的地址 ) + 8 + 偏移量
下一条指令位置的计算方法:
(当前指令的地址 ) + 4
2.5 ARM 的存储器结构
 存储器格式

存储器系统有两种映射机制:
小端存储器系统:
低位地址
大端模式
高位地址
0x12 0x34 0x56 0x78
在小端格式中,高位数字存放在高位字节
中。因此存储器系统字节 0 连接到数据线 7 ~ 0 。
小端模式
低位地址 高位地址
大端存储器系统:
0x78 0x56 0x34 0x12

在大端格式中,高位数字存放在低位字节
0x12345678 字数据的大小端存储方式
中。因此存储器系统字节 0 连接到数据线 31 ~ 24 。
 存储器格式

一个基于 ARM 内核的芯片可以只支持大端模式


或小端模式,也可以两者都支持。
在 ARM 指令集中不包含任何直接选择大小端
的指令,但是一个同时支持大小端模式的 ARM 芯
片可以通过硬件配置(一般使用芯片的引脚来配
置)来匹配存储器系统所使用的规则。

注意:如果实际的存储器格式与芯片的存储器格式
不符时,只有以字为单位的数据存取才正确,否则
将出现不可预期的结果。
2.5 ARM 的存储器结构
 存储器映射的 I/O

基于 ARM 内核的芯片具有许多的外设,这些外
设访问的标准方法是使用存储器映射的 I/O ,为外设
的每个寄存器都分配一个地址。通常,从这些地址
装载数据用于读入,向这些地址保存数据用于输出。
有些地址的装载和保存用于外设的控制功能,而不
是输入或输出功能。
注意:存储器映射的 I/O 位置的操作不同于正常的存
储器位置的操作。通常,存储器映射的 I/O 位置没有
高速缓存和无缓冲区。
2.6 ARM 微处理器指令系

 简介

 ARM 处理器是基于精简指令集计算机 (RISC) 原理设计的,指令集


和相关译码机制较为简单。
 ARM 具有 32 位 ARM 指令集和 16 位 Thumb 指令集。
 ARM 指令集效率高,但是代码密度低 ;
 Thumb 指令集具有较高的代码密度,却仍然保持 ARM 的大多数性
能上的优势,它是 ARM 指令集的子集。
 所有的 ARM 指令都是可以有条件执行的,而 Thumb 指令仅有一
条指令 B 具备条件执行功能。
 ARM 程序和 Thumb 程序可相互调用,相互之间的状态切换开销几
乎为零。
2.6.1 ARM 处理器寻址方式

寻址方式是根据指令中给出的地址码字段来实现寻
找真实操作数地址的方式。 ARM 处理器具有 9 种基
本寻址方式。
1. 寄存器寻址 2. 立即寻址
3. 寄存器移位寻址 4. 寄存器间接寻址
5. 变址寻址 6. 多寄存器寻址
7. 堆栈寻址 8. 块复制(块拷贝)寻址
9. 相对寻址
2.6.1 ARM 处理器寻址方式

 寻址方式分类——寄存器寻址

操作数的值在寄存器中,指令中的地址码字段指
出的是寄存器编号,指令执行时直接取出寄存器值
来操作。寄存器寻址指令举例如下:
MOV R1,R2 ; 将 R2 的值存入 R1

SUB R0,R1,R2 ;R2 0xAA R2 的值,结果保存到 R0


将 R1 的值减去
R1 0xAA
0x55

MOV R1,R2
2.6.1 ARM 处理器寻址方式

 寻址方式分类——立即寻址

立即寻址指令中的操作码字段后面的地址码部分
即是操作数本身,也就是说,数据就包含在指令当
中,取出指令也就取出了可以立即使用的操作数
程序存储
(这样的数称为立即数 )。立即寻址指令举例如下:
MOV R0,#0xFF00
SUBS R0,R0,#1 从代码中获得数据
;R0 减 1 ,结果放入 R0 ,并且影响标志

R0 0xFF00
0x55
MOV R0,#0xFF000 ; 将立即数 0xFF000 装入 R0 寄存器
MOV R0,#0xFF00
2.6.1 ARM 处理器寻址方式

 寻址方式分类——寄存器移位寻址

寄存器移位寻址是 ARM 指令集特有的寻址方式。


当第 2 个操作数是寄存器移位方式时,第 2 个寄存
器操作数在与第 1 个操作数结合之前,选择进行移
位操作。寄存器移位寻址指令举例如下: 逻辑左移 3 位
MOV R2 #30x01 ;R2 的值左移0x08
R0,R2,LSL 3 位,结果放入 R0
, ; 即是 R0=R2×8
R0 0x55
0x08
ANDS R1,R1,R2,LSL R3 ;R2 的值左移 R3 位,然后和 R1 相
;“ 与”操作,结果放入 R1
MOV R0,R2,LSL #3
2.6.1 ARM 处理器寻址方式

 寻址方式分类——寄存器间接寻址

寄存器间接寻址指令中的地址码给出的是一个通
用寄存器的编号,所需的操作数保存在寄存器指定
地址的存储单元中,即寄存器为操作数的地址指针。
0x40000000
寄存器间接寻址指令举例如下: 0xAA
LDR R1,[R2] ; 将 R2 指向的存储单元的数据读出
R2 0x40000000
; 保存在 R1 中
R0 0xAA
0x55
SWP R1,R1,[R2] ; 将寄存器 R1 的值和 R2 指定的存储
; 单元的内容交换
LDR R1,[R2]
2.6.1 ARM 处理器寻址方式

 寻址方式分类——变址(基址)寻址

基址寻址就是将基址寄存器的内容与指令中给出
的偏移量相加,形成操作数的有效地址。基址寻址
用于访问基址附近的存储单元,常用于查表、数组
0x4000000C
操作、功能部件寄存器访问等。基址寻址指令举例 0xAA
如下:
将 R3+0x0C 作 R3 0x40000000
LDR R2,[R3,#0x0C] ; 读取 R3+0x0C 地址上的存储单元
为地址装载数据 R2 0xAA
0x55
; 的内容,放入 R2
STR R1,[R0,#-4]! ; 先 R0=R0-4 ,然后把 R1 寄存器的
值 LDR R2,[R3,#0x0C]
; 保存到 R0 指定的存储单元
2.6.1 ARM 处理器寻址方式

 寻址方式分类——多寄存器寻址

多寄存器寻址一次可传送几个寄存器值,允许一
条指令传送 16 个寄存器的任何子集或所有寄存器。
多寄存器寻址指令举例如下:
R6 0x04
0x?? 0x04 0x4000000C
LDMIAR4 0x03
0x??
R1!,{R2-R7,R12} ; 将 R10x03
指向的单元中的数据读出到
0x40000008
R3 0x02
0x?? R7 、 R12
;R2 ~ 0x02 中 (R1 自动加 4
0x40000004
递增 )
R2 0x01
0x?? 0x01 0x40000000
STMIA R0!,{R2-R7,R12} ; 将寄存器 R2 ~ R7 、 R12 的值保
R1 0x40000010
0x40000000 存储器
; 存到 R0 指向的存储单元中
LDMIA R1!,{R2-R4,R6}
;(R0 自动加 4 递增 )
2.6.1 ARM 处理器寻址方式

 寻址方式分类——堆栈寻址

堆栈是一个按特定顺序进行存取的存储区,操作顺序为
“后进先出” 。存储器堆栈可分为两种:
向上生长:入栈操作向高地址方向生长,称为递增堆栈

向下生长:入栈操作向低地址方向生长,称为递减堆栈
2.6.1 ARM 处理器寻址方式

 寻址方式分类——堆栈寻址

堆栈压栈 0x12345678

SP 栈顶 栈底

向上 堆栈存 向下
栈区 增长 增长 栈区
储区

栈底 栈顶 SP

0x12345678 堆栈压栈
2.6.1 ARM 处理器寻址方式

 寻址方式分类——堆栈寻址

满堆栈:堆栈指针指向最后压入的堆栈的有效数据项;
空堆栈:堆栈指针指向下一个待压入数据的空位置。

压栈 0x12345678 压栈
SP 栈顶
SP 栈顶 0x12345678 SP 栈顶 0x12345678
SP 栈顶

满堆栈 空堆栈

栈底 栈底
2.6.1 ARM 处理器寻址方式
 寻址方式分类——堆栈寻址
所以可以组合出四种类型的堆栈方式:
满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。

指令如 LDMFA 、 STMFA 等;


空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。
指令如 LDMEA 、 STMEA 等;
满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。
指令如 LDMFD 、 STMFD 等;
空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。
指令如 LDMED 、 STMED 等。
2.6.1 ARM 处理器寻址方式
 寻址方式分类——堆栈寻址

 FD 满递减堆栈;
 ED 空递减堆栈;
 FA 满递增堆栈;
 EA 空递增堆栈。
2.6.1 ARM 处理器寻址方式
 寻址方式分类——块复制(块拷贝)寻址
多寄存器传送指令用于将一块数据从存储器
的某一位置拷贝到另一位置。 如:

STMIA R0!,{R1-R7} ; 将 R1 ~ R7 的数据保存到存储器中



; 存储指针在保存第一个值之后增加,
; 增长方向为向上增长。
STMIB R0!,{R1-R7} ; 将 R1 ~ R7 的数据保存到存储器中

; 存储指针在保存第一个值之前增加,
2.6.1 ARM 处理器寻址方式
 寻址方式分类——块复制(块拷贝)寻址
 IA 每次传送后地址加 4 ;
 IB 每次传送前地址加 4 ;
 DA 每次传送后地址减 4 ;
 DB 每次传送前地址减 4 ;
多寄存器 load 和 store 指令的堆栈和块拷贝对照
   
递增 递减
   
满 空 满 空

STMIB     LDMIB
先增 STMFA LDMED
增值
后增   STMIA LDMIA  
STMEA LDMFD

  LDMDB STMDB  
先减 LDMEA STMFD
减值
LDMDA     STMDA
后减 LDMFA STMED
2.6.1 ARM 处理器寻址方式
 寻址方式分类——相对寻址
相对寻址是基址寻址的一种变通。由程序计数器 PC 提供
基准地址,指令中的地址码字段作为偏移量,两者相加后得
到的地址即为操作数的有效地址。相对寻址指令举例如下:

BL SUBR1 ; 调用到 SUBR1 子程序


BEQ LOOP ; 条件跳转到 LOOP 标号处
...
LOOP MOV R6,#1
...
SUBR1 ...
 ARM 程序( Windows 下 MDK 的汇编语言程序结构)

; 文件名: TEST1.S
使用“;”进行注释
; 功能:实现两个寄存器相加
; 说明:使用 ARMulate 软件仿真调试
AREA ARMadd,CODE,READONLY; 定义名为 ARMadd 的只读属性代码

ENTRY ; 伪指令,标识程序入口
START MOV R0,#0 ; 设置参数
MOV R1,#10
LOOP BL ADD_SUB ; 调用子程序 ADD_SUB
B LOOP ; 跳转到 LOOP
实际代码段
ADD_SUB 标号顶格写
ADDS R0,R0,R1 ;R0 = R0 + R1
MOV PC,LR
声明文件结束 ; 子程序返回
END ; 文件结束代码
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 跳转指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集——指令格式

ARM 指令的基本格式如下:
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}

其中 <> 号内的项是必须的, {} 号内的项是可选的。


各项的说明如下:
opcode :指令助记符; cond :执行条件;
S :是否影响 CPSR 寄存器的值;
Rd :目标寄存器; Rn :第 1 个操作数的寄存器

2 指令集介绍
 ARM 指令集——第 2 个操作数

ARM 指令的基本格式如下:
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}

灵活使用第 2 个操作数“ operand2” 能够提高代码效率。


它有如下的形式:
#immed_8r—— 常数表达式;

Rm—— 寄存器方式;
Rm,shift—— 寄存器移位方式;
2 指令集介绍
 ARM 指令集——第 2 个操作数

#immed_8r—— 常数表达式
该常数必须对应 8 位位图,即一个 8 位的常数通
过循环右移偶数位得到。
循环右移 10 位
00000000000000000000000000010010
0x00 0x00 0x00 0x12
8 位常数
00000100100000000000000000000000
0x04 0x80 0x00 0x00
2 指令集介绍
 ARM 指令集——第 2 个操作数

#immed_8r—— 常数表达式
该常数必须对应 8 位位图,即一个 8 位的常数通
过循环右移偶数位得到。
例如:
AND R1,R2,#0x0F
2 指令集介绍
 ARM 指令集——第 2 个操作数

Rm—— 寄存器方式
在寄存器方式下,操作数即为寄存器的数值。
例如:
SUB R1,R1,R2
2 指令集介绍
 ARM 指令集——第 2 个操作数

Rm,shift—— 寄存器移位方式
将寄存器的移位结果作为操作数,但 Rm 值保持不变
,移位方法如下:

操作码 说明 操作码 说明
ASR #n 算术右移 n 位 ROR #n 循环右移 n 位
LSL #n 逻辑左移 n 位 RRX 带扩展的循环右移 1 位
LSR #n 逻辑右移 n 位
2 指令集介绍
 ARM 指令集——第 2 个操作数
LSL 移位操作: 0

LSR 移位操作: 0

ASR 移位操作:
符号位填充空位
ROR 移位操作:

RRX 移位操作: C
右移一位空位 c

注意:只有带扩展的循环右移 RRX 是将内容移动一位,无需指定移动位数
2 指令集介绍
 ARM 指令集——第 2 个操作数

Rm,shift—— 寄存器移位方式
例如:
ADD R1,R1,R1,LSL #3 ;R1=R1+R1*8=9R1
SUB R1,R1,R2,LSR R3 ;R1=R1-(R2/2R3)
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集——条件码
ARM 指令的基本格式如下:
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}

使用条件码“ cond” 可以实现高效的逻辑操作,提高代


码效率。
所有的 ARM 指令都可以条件执行,而 Thumb 指令
只有 B (跳转)指令具有条件执行 功能。
如果指令不标明条件代码,将默认为无条件( AL )执行

• 指令条件码表
操作码 条件助记符 标志 含义
0000 EQ Z=1 相等
0001 NE Z=0 不相等
0010 CS/HS C=1 无符号数大于或等于
0011 CC/LO C=0 无符号数小于
0100 MI N=1 负数
0101 PL N=0 正数或零
0110 VS V=1 溢出
0111 VC V=0 没有溢出
1000 HI C=1,Z=0 无符号数大于
1001 LS C=0,Z=1 无符号数小于或等于
1010 GE N=V 有符号数大于或等于
1011 LT N!=V 有符号数小于
1100 GT Z=0,N=V 有符号数大于
1101 LE Z=1,N!=V 有符号数小于或等于
1110 AL 任何 无条件执行 (指令默认条件 )
1111 NV 任何 从不执行 (不要使用 )
2 指令集介绍
 ARM 指令集——条件码

示例:
C 代码: 对应的汇编代码:
If(a > b) CMP R0,R1 ;R0 与 R1 比较
a++; ADDHI R0,R0,#1 ; 若 R0>R1 ,则 R0=R0+1
Else ADDLS R1,R1,#1 ; 若 R0≤R1 ,则 R1=R1+1
b++;
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
 ARM 指令集——存储器访问指令

ARM 处理器是典型的 RISC 处理器,对存储器的


访问只能使用加载和存储指令实现。
ARM 处理器对 RAM 、外围 IO 、程序数据的
访问均要通过加载 /存储指令进行。

存储器访问指令分为:
1 、单寄存器操作指令;
2 、多寄存器操作指令;
3 、寄存器和存储器交换指令
• ARM 存储器访问指令——单寄存器加载
助记符 说明 操作 条件码位置

Rd←[addressing] ,
LDR Rd,addressing 加载字数据 LDR{cond}
addressing 索引
Rd←[addressing] ,
LDRB Rd,addressing 加载无符号字节数据 LDR{cond}B
addressing 索引
以用户模式加载字数据 Rd←[addressing] ,
LDRT Rd,addressing LDR{cond}T
(特权模式时) addressing 索引
以用户模式加载无符号
字节数据 Rd←[addressing] ,
LDRBT Rd, addressing LDR{cond}BT
addressing 索引
(特权模式时)
Rd←[addressing] ,
LDRH Rd, addressing 加载无符号半字数据 LDR{cond}H
addressing 索引

Rd←[addressing] ,
LDRSB Rd, addressing 加载有符号字节数据 LDR{cond}SB
addressing 索引
Rd←[addressing] ,
LDRSH Rd, addressing 加载有符号半字数据 LDR{cond}SH
addressing 索引
• ARM 存储器访问指令——单寄存器存储

助记符 说明 操作 条件码位置
STR Rd, addressing 存储字数据 [addressing]←Rd , STR{cond}
addressing 索引

STRB Rd,addressing 存储字节数据 [addressing]←Rd , STR{cond}B


addressing 索引

STRT Rd,addressing 以用户模式存储字数据 [addressing]←Rd , STR{cond}T


addressing 索引

STRBT Rd,addressing 以用户模式存储字节数据 [addressing]←Rd , STR{cond}B


addressing 索引 T

STRH Rd,addressing 存储半字数据 [addressing] ←Rd , STR{cond}H


addressing 索引
LDR/STR 指令用于对内存变量的访问、内存缓冲
区数据的访问、查表、外围部件的控制操作等。
所有单寄存器加载 /存储指令可分为
“ 字和无符号字节加载存储指令”和
“ 半字和有符号字节加载存储指令。
•( 1 ) LDR 和 STR—— 字和无符号字节加载 /存储
指令
LDR 指令用于从内存中读取单一字或字节数据存
入寄存器中, STR 指令用于将寄存器中的单一字或字
节数据保存到内存。指令格式如下:
LDR{cond}{T} Rd,< 地址 > ; 将指定地址上的字数据读入 Rd
STR{cond}{T} Rd,< 地址 > ; 将 Rd 中的字数据存入指定地

LDR{cond}B{T} Rd,< 地址 > ; 将指定地址上的字节数据读入
Rd
其中, T 为可选后缀。若指令有
STR{cond}B{T} T ,那么即使处理器
Rd,< 地址 > ; 将 Rd 中的字节数据存入指定
是在特权模式下,存储系统也将访问看成是在用户模式
地址
下进行的。 T 在用户模式下无效,不能与前索引偏移一
起使用 T 。
B 为 1 表示字节访
问,为 0 表示字访

P 表示前 /后变址
L 用于区别加载( L 为
指令执行的条件码 1 )或存储( L 为 0 )

I为 0 时,偏移量为 为指令的寻址方式
12 位立即数,为 1
Rd 为源 /目标寄存器
时,偏移量为寄存
器移位 Rn 为基址寄存器
U 表示加 /减 W 表示回写
•LDR/STR 指令寻址非常灵活,它由两部分组成,其中一部
分为一个基址寄存器,可以为任一个通用寄存器;另一部分
为一个地址偏移量。地址偏移量有以下 3 种格式:
立即数。立即数可以是一个无符号的数值。这个数据可以加
到基址寄存器,也可以从基址寄存器中减去这个数值。
如: LDR R1,[R0,#0x12]
寄存器。寄存器中的数值可以加到基址寄存器,也可以从基
址寄存器中减去这个数值。
如: LDR R1,[R0,R2]
寄存器及移位常数。寄存器移位后的值可以加到基址寄存器
,也可以从基址寄存器中减去这个数值。
如: LDR R1,[R0,R2,LSL #2]
从寻址方式的地址计算方法分,加载 /存储指令有以下 4
种格式:
零偏移。 如: LDR Rd,[Rn]
前索引偏移。 如: LDR Rd,[Rn,#0x04]!
程序相对偏移。 如: LDR Rd,labe1
后索引偏移。 如: LDR Rd,[Rn],#0x04

注意:大多数情况下,必须保证字数据操作的地址是 32 位对
齐的。
•( 2 ) LDR 和 STR—— 半字和有符号字节加载 /存储指

这类 LDR/STR 指令可加载有符号半字或字节,可加载 /存储无
符号半字。偏移量格式、寻址方式与加载 /存储字和无符号字节指令
相同。
LDR{cond}SB Rd,< 地址 > ; 将指定地址上的有符号字节读入 Rd
LDR{cond}SH Rd,< 地址 > ; 将指定地址上的有符号半字读入 Rd
LDR{cond}H Rd,< 地址 > ; 将指定地址上的半字数据读入 Rd
STR{cond}H Rd,< 地址 > ; 将 Rd 中的半字数据存入指定地址
注意:
1. 有符号位半字 /字节加载是指用符号位加载扩展到 32 位,无符号
半字加载是指用零扩展到 32 位;
2. 半字读写的指定地址必须为偶数,否则将产生不可靠的结果;
S 为 1 表示有符号访问
W 表示回写
,为 0 表示无符号访问
P 表示前 /后变址
H 为 1 表示半字访问,
指令执行的条件码 为 0 表示字节访问

U 表示加 /减 为指令的寻址方式
I为 0 时,偏移量为 Rd 为源 /目标寄存器
12 位立即数,为 1
Rn 为基址寄存器
时,偏移量为寄存
器移位 L 用于区别加载( L 为
1 )或存储( L 为 0 )
•LDR 和 STR 指令应用示例:

1. 加载 /存储字和无符号字节指令
LDR R2,[R5] ; 将 R5 指向地址的字数据存入 R2
STR R1,[R0,#0x04] ; 将 R1 的数据存储到 R0+0x04 地址
LDRB R3,[R2],#1 ; 将 R2 指向地址的字节数据高位 0 扩展至 32 位存入 R3 , R2
= R2+1
STRB R6,[R7] ; 将 R6 的最低字节数据存入 R7 指向地址的一个存储单元中
2. 加载 /存储半字和有符号字节指令
LDRSB R1,[R0,R3] ; 将 R0+R3 地址上的字节数据存入 R1 ,
; 高 24 位用符号扩展
LDRH R6,[R2],#2 ; 将 R2 指向地址的半字数据存入 R6 ,高 16 位用 0
扩展
; 读出后, R2=R2+2
STRH R1,[R0,#2]! ; 将 R1 的半字数据保存到 R0+2 地址,
; 只修改低 2 字节数据, R0=R0+2
• ARM 存储器访问指令——多寄存器存取

助记符 说明 操作 条件码位置
LDM{mode} Rn{!},reglist 多寄存器加载 reglist←[Rn...] , Rn 回 LDM{cond}
写等 {mode}
STM{mode} Rn{!},reglist 多寄存器存储 [Rn...]←reglist,Rn 回 写 STM{cond}
等 {mode}

多寄存器加载 /存储指令可以实现在一组寄存器和一块连续的内存单
元之间传输数据。

•LDM 为加载多个寄存器; STM 为存储多个寄存器。


•允许一条指令传送 16 个寄存器的任何子集或所有寄存器。
•它们主要用于现场保护、数据复制、常数传递等。
• ARM 存储器访问指令——多寄存器存取
多寄存器加载 /存储指令格式如下:
LDM{cond}< 模式 > Rn{!},reglist{^}
STM{cond}< 模式 > Rn{!},reglist{^}
cond :指令执行的条件;
模式:控制地址的增长方式,一共有 8 种模式;
!: 表示在操作结束后,将最后的地址写回 Rn 中;
reglist :表示寄存器列表,可以包含多个寄存器,它们使用“ ,” 隔开,
如 {R1,R2,R6-R9} ,寄存器由小到大排列;

^ :加入该后缀后(注意:该后缀不允许在用户模式或系统模式下使用)。
( 1 )进行数据传送且寄存器列表不包含 PC 时,加载 /存储的寄存器是
用户模式下的,而不是当前模式的寄存器。
( 2 )若在 LDM 指令且寄存器列表中包含有 PC 时使用,那么除了正常的
多寄存器传送外,还将 SPSR 也拷贝到 CPSR 中,这可用于异常处理
返回。
• ARM 存储器访问指令——多寄存器存取
•LDM 和 STM—— 多寄存器加载 /存储指令编码

指令执行的条件码

P 表示前 /后变址 寄存器列表


U 表示加 /减 Rn 为基址寄存器
S 对应于指令中 L 用于区别加载( L 为
的” ^” 符号 1 )或存储( L 为 0 )
W 表示回写
• ARM 存储器访问指令——多寄存器存取
多寄存器加载 /存储指令的 8 种模式如下表所示,右边四种为堆
栈操作、左边四种为数据传送操作。
模式 说明 模式 说明
IA 每次传送后地址加 4 FD 满递减堆栈
IB 每次传送前地址加 4 ED 空递减堆栈
DA 每次传送后地址减 4 FA 满递增堆栈
DB 每次传送前地址减 4 EA 空递增堆栈
数据块传送操作 堆栈操作

进行数据复制时,先设置好源数据指针和目标指针,然后使用
块 拷 贝 寻 址 指 令
LDMIA/STMIA 、 LDMIB/STMIB 、 LDMDA/STMDA 、 LDMDB/S
TMDB 进行读取和存储 。
进行堆栈操作操作时,要先设置堆栈指针( SP ),然后使用堆栈寻址
指令 STMFD/LDMFD 、 STMED/LDMED 、 STMFA/LDMFA 和
STMEA/LDMEA 实现堆栈操作。
• ARM 存储器访问指令——多寄存器存取
R1’  4014H 4014H
数据块传送指令操作
R7 4010H R1’  R7 4010H
过程如右图所示,其
R6 400CH R6 400CH
中 R1 为 指 令 执 行 前
R1  R5 4008H R5 4008H
的基址寄存器, R1’
4004H R1  4004H
则为指令执行后的基
4000H 4000H
址寄存器。
指令 STMIA R1!,{R5- 指令 STMIB R1!,{R5-
R7} R7}

4014H R1  4014H
R1  R7 4010H R7 4010H
R6 400CH R6 400CH
R5 4008H R1’  R5 4008H
R1’  4004H 4004H
4000H 4000H

指令 STMDA R1!,{R5- 指令 STMDB R1!,{R5-


R7} R7}
• ARM 存储器访问指令——多寄存器存取
堆栈操作和数据块传送指令类似,也有 4 种模式,它们之间的
关系如下表所示:
数据块传送 堆栈操作 数据块传送 堆栈操作
说明 说明
存储 压栈 加载 出栈
STMDA STMED 空递减 LDMDA LDMFA 满递减
STMIA STMEA 空递增 LDMIA LDMFD 满递增
STMDB STMFD 满递减 LDMDB LDMEA 空递减
STMIB STMFA 满递增 LDMIB LDMED 空递增

; 使用数据块传送指令进行堆栈操作 ; 使用堆栈指令进行堆栈操作
STMDA R0!,{R5-R6} STMED R0!,{R5-R6}
. . . . . .
LDMIB R0!,{R5-R6} LDMED R0!,{R5-R6}

两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出
栈操作编程很简单(只要前后一致即可),而使用数据块指令进行压
栈和出栈操作则需要考虑空与满、加与减对应的问题。
• ARM 存储器访问指令——寄存器和存储器交换指令
助记符 说明 操作 条件码位置
SWP Rd,Rm,[Rn] 寄存器和存储器字数据 Rd←[Rn] , [Rn]←Rm SWP{cond}
交换 (Rn≠Rd 或 Rm)
SWPB Rd,Rm,[Rn] 寄存器和存储器字节数 Rd←[Rn] , [Rn]←Rm SWP{cond}B
据交换 (Rn≠Rd 或 Rm)

SWP 指令用于将一个内存单元 ( 该单元地址放在寄存器 Rn 中 ) 的内


容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该内
存单元中。使用 SWP 可实现信号量操作。
指令格式如下:
SWP{cond}{B} Rd,Rm,[Rn]

B : 为可选后缀,若有 B ,则交换字节,否则交换 32 位字;


Rd : 用于保存从存储器中读入的数据;
Rm :用于存储到存储器中的数据,若 Rm 与 Rn 相同,则为寄存器

存储器内容进行交换;
Rn : 为要进行数据交换的存储器地址, Rn 不能与 Rd 和 Rm 相
• ARM 存储器访问指令——寄存器和存储器交换指令

•SWP 和 SWPB—— 寄存器和存储器交换指令编码

指令执行的条件码 Rm 源寄存器
B 用于区别无符号 Rd 目标寄存器
字节( B 为 1 )或
字( B 为 0 ) Rn 为基址寄存器

•SWP 指令应用示例:
SWP R1,R1,[R0] ; 将 R1 的内容与 R0 指向的存储单元的内容进行交换
SWPB R1,R2,[R0] ; 将 R0 指向的存储单元的内容读取一字节数据到 R1

;(高 24 位清零 ),并将 R2 的内容写入到该内存单元

ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集—— ARM 数据处理指令
数据处理指令大致可分为 3 类:
数据传送指令;

算术逻辑运算指令;

比较指令。

数据处理指令只能对寄存器的内容进行操作,
而不能对内存中的数据进行操作。

所有 ARM 数据处理指令均可选择使用 S 后缀,


并影响状态标志。
• ARM 数据处理指令——指令编码
opcode 操作码功能表
指令执行的条件码 操作码 指令助记符
第二操作数
说明
0000 AND 逻辑与操作指令
0001 EOR 逻辑异或操作指令
0010 SUB 减法运算指令
0011 RSB 逆向减法指令
I 用于区别立即数 0100 ADD
Rd 目标寄存器
加法运算指令
( I为 1 )和寄存器 0101 ADC Rn 第一操作数寄存器
带进位加法
移位( I为 0 ) 0110 SBC 带进位减法指令
S 设置条件码,与指令
opcode 数 据 处 理 指 0111 RSC 带进位逆向减法指令
中的 S 位对应
令操作码 1000 TST 位测试指令
1001 TEQ 相等测试指令
1010 CMP 比较指令
1011 CMN 负数比较指令
1100 ORR 逻辑或操作指令
1101 MOV 数据传送
1110 BIC 位清除指令
1111 MVN 数据非传送
• ARM 数据处理指令——数据传送
助记符 说明 操作 条件码位置
MOV Rd,operand2 数据传送 Rd←operand2 MOV{cond}{S}
MVN Rd,operand2 数据非传送 Rd←(~operand2) MVN{cond}{S}
• ARM 数据处理指令——数据传送
助记符 说明 操作 条件码位置
MOV Rd,operand2 数据传送 Rd←operand2 MOV{cond}{S}
MVN Rd,operand2 数据非传送 Rd←(~operand2) MVN{cond}{S}

MOV 指令将 8 位图立即数或寄存器传送到目标寄存器( Rd ),可用


于移位运算等操作。指令格式如下:
MOV{cond}{S} Rd,operand2

MOV 指令举例如下:
MOV R1,#0x10 ;R1=0x10
MOV R0,R1 ;R0=R1
MOVS R3,R1,LSL #2 ;R3=R1<<2 ,并影响标志位
MOV PC,LR ;PC=LR ,子程序返回
• ARM 数据处理指令——数据传送
助记符 说明 操作 条件码位置
MOV Rd,operand2 数据传送 Rd←operand2 MOV{cond}{S}
MVN Rd,operand2 数据非传送 Rd←(~operand2) MVN{cond}{S}

MVN 指令将 8 位图立即数或寄存器( operand2 )按位取反后传送到


目标寄存器( Rd ),因为其具有取反功能,所以可以装载范围更广的立
即数。
指令格式如下:
MVN{cond}{S} Rd,operand2

MVN 指令举例如下:
MVN R1,#0xFF ;R1=0xFFFFFF00
MVN R1,R2 ;将 R2 取反,结果存到 R1
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry

加法运算指令—— ADD 指令将 operand2 的值与 Rn 的值相加,结果


保存到 Rd 寄存器。指令格式如下:
ADD{cond}{S} Rd,Rn,operand2

应用示例:
ADDS R1,R1,#1 ;R1=R1+1 ,并影响标志位
ADD R1,R1,R2 ;R1=R1+R2
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry

减法运算指令—— SUB 指令用寄存器 Rn 减去 operand2 ,结果保存


到 Rd 中。指令格式如下:
SUB{cond}{S} Rd,Rn,operand2

应用示例:
SUBS R0,R0,#1 ;R0=R0-1 ,并影响标志位
SUBS R2,R1,R2 ;R2=R1-R2 ,并影响标志位
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry

逆向减法运算指令—— RSB 指令将 operand2 的值减去 Rn ,结果保存


到 Rd 中。指令格式如下:
RSB{cond}{S} Rd,Rn,operand2

应用示例:
RSB R3,R1,#0xFF00 ;R3=0xFF00-R1
RSBS R1,R2,R2,LSL #2 ;R1=(R2<<2)-R2=R2×3
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry

带进位加法指令—— ADC 将 operand2 的值与 Rn 的值相加,再加上


CPSR 中的 C 条件标志位,结果保存到 Rd 寄存器。指令格式如下:
ADC{cond}{S} Rd,Rn,operand2

应用示例(使用 ADC 实现 64 位加法,结果存于 R1 、 R0 中):


ADDS R0,R0,R2 ;R0 等于低 32 位相加,并影响标志位
ADC R1,R1,R3 ;R1 等于高 32 位相加,并加上低位进位
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry

带进位减法指令—— SBC 用寄存器 Rn 减去 operand2 ,再减去 CPSR


中的 C 条件标志位的非 (即若 C 标志清零表示有借位,则结果减去 1),结
果保存到 Rd 中。指令格式如下:
SBC{cond}{S} Rd,Rn,operand2

应用示例(使用 SBC 实现 64 位减法,结果存于 R1 、 R0 中):


SUBS R0,R0,R2 ; 低 32 位相减,并影响标志位
SBC R1,R1,R3 ;高 32 位相减,并减去低位借位
• ARM 数据处理指令——算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
Rd←Rn-operand2-
SBC Rd, Rn, operand2 带进位减法指令 SBC{cond}{S}
(NOT)Carry
带进位逆向减法 Rd←operand2-Rn-
RSC Rd, Rn, operand2 RSC{cond}{S}
指令 (NOT)Carry

带进位逆向减法指令—— RSC 指令用寄存器 operand2 减去 Rn ,再减


去 CPSR 中的 C 条件标志位,结果保存到 Rd 中。指令格式如下:
RSC{cond}{S} Rd,Rn,operand2

应用示例(使用 RSC 指令实现求 64 位数值的负数 。 R3R2= - R1R0 ):


RSBS R2,R0,#0
RSC R3,R1,#0
• ARM 数据处理指令——逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}
• ARM 数据处理指令——逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}

逻辑与操作指令—— AND 指令将 operand2 的值与寄存器 Rn 的值按


位作逻辑“与”操作,结果保存到 Rd 中。指令格式如下:
AND{cond}{S} Rd,Rn,operand2

应用示例:
ANDS R0,R0,#0x01 ;R0=R0&0x01 ,取出最低位数据
AND R2,R1,R3 ;R2=R1&R3
• ARM 数据处理指令——逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}

逻辑或操作指令—— ORR 指令将 operand2 的值与寄存器 Rn 的值按


位作逻辑“或”操作,结果保存到 Rd 中。指令格式如下:
ORR{cond}{S} Rd,Rn, operand2
应用示例:
1、 ORR R0,R0,#0x0F ;将 R0 的低 4 位置 1
2、 MOV R1,R2,LSR #24 ;使用 ORR 指令将 R2 的高 8 位
ORR R3,R1,R3,LSL #8 ;数据移入到 R3 低 8 位中
• ARM 数据处理指令——逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}

逻辑异或操作指令—— EOR 指令将 operand2 的值与寄存器 Rn 的值


按位作逻辑“异或”操作,结果保存到 Rd 中。指令格式如下:
EOR{cond}{S} Rd,Rn, operand2 位

应用示例:
EOR R1,R1,#0x0F ;将 R1 的低 4 位取反
EOR R2,R1,R0 ;R2=R1^R0
EORSR0,R5,#0x01 ; 将 R5 和 0x01 进行逻辑异或,
;结果保存到 R0 ,并影响标志
• ARM 数据处理指令——逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}

位清除指令—— BIC 指令将寄存器 Rn 的值与 operand2 的值的反码按


位作逻辑“与”操作,结果保存到 Rd 中。指令格式如下:
BIC{cond}{S} Rd,Rn, operand2

应用示例:
BIC R1,R1,#0x0F ;将 R1 的低 4 位清零,其它位不变
BIC R1,R2,R3 ;将 R3 的反码和 R2 相逻辑
“与”,
;结果保存到 R1 中
• ARM 数据处理指令——比较指令 (自动影响标志位 )

助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2 相等测试指令 TEQ{cond}
^ operand2
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2
比较指令—— CMP相等测试指令
指令将寄存器 Rn 的值减去 operand2TEQ{cond}
的值,根据
^ operand2
操作的结果更新 CPSR 中的相应条件标志位,以便后面的指令根据相应的
条件标志来判断是否执行。指令格式如下:
CMP{cond} Rn, operand2
应用示例:
CMP R1,#10 ; R1 与 10 比较,设置相关标志位
CMP R1,R2 ; R1 与 R2 比较,设置相关标志位
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2 相等测试指令 TEQ{cond}
^ operand2

注意: CMP 指令与 SUBS 指令的区别在于 CMP 指令不保存运算结果。在


进行两个数据的大小判断时,常用 CMP 指令及相应的条件码来操作。
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2 相等测试指令
负数比较指令—— CMN 指令使用寄存器 TEQ{cond}的值
Rn 的值加上 operand2
^ operand2
,根据操作的结果更新 CPSR 中的相应条件标志位,以便后面的指令根据
相应的条件标志来判断是否执行。指令格式如下:
CMN{cond} Rn, operand2
应用示例:
CMN R0,#1 ; R0+1 ,判断 R0 是否为 1 的补码
;如果是,则设置 Z 标志位
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2 相等测试指令 TEQ{cond}
^ operand2

注 意 : CMN 指 令 与 ADDS 指 令 的 区 别 在 于 CMN 指 令 不 保 存 运 算 结


果。 CMN 指令可用于负数比较,比如 CMN R0,#1 指令则表示 R0 与 -1 比
较,若 R0 为 -1( 即 1 的补码 ),则 Z 置位;否则 Z 复位。
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2
位测试指令—— 相等测试指令
TST 指令将寄存器 TEQ{cond}
的值与 operand2 的值按位作逻
^Rn
operand2
辑“与”操作,根据操作的结果更新 CPSR 中的相应条件标志位,以便后
面的指令根据相应的条件标志来判断是否执行。指令格式如下:
TST{cond} Rn, operand2
应用示例:
TST R0,#0x01 ; 判断 R0 的最低位是否为 0
TST R1,#0x0F ; 判断 R1 的低 4 位是否为 0
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2 相等测试指令 TEQ{cond}
^ operand2

注 意 : TST 指 令 与 ANDS 指 令 的 区 别 在 于 TST 指 令 不 保 存 运 算 结


果。 TST 指令通常与 EQ 、 NE 条件码配合使用,当所有测试位均为 0 时
, EQ 有效,而只要有一个测试位不为 0 ,则 NE 有效。
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标 志 N 、 Z←Rn ^
TEQ Rn, operand2 相等测试指令
相等测试指令—— TEQ 指令将寄存器 TEQ{cond}
Rn 的值与 operand2 的值按位
operand2
作逻辑“异或”操作,根据操作的结果更新 CPSR 中的相应条件标志位,
以便后面的指令根据相应的条件标志来判断是否执行。指令格式如下:
TEQ{cond} Rn, operand2
应用示例:
TEQ R0,R1 ; 比较 R0 与 R1 是否相等 (不影响 V 位
和C 位)
• ARM 数据处理指令——比较指令
助记符 说明 操作 条件码位置
标 志
CMP Rn, operand2 比较指令 N 、 Z 、 C 、 V←Rn- CMP{cond}
operand2
标 志
CMN Rn, operand2 负数比较指令 N 、 Z 、 C 、 V←Rn+ope CMN{cond}
rand2
标志 N 、 Z 、 C 、 V←Rn
TST Rn, operand2 位测试指令 TST{cond}
& operand2
标志 N 、 Z 、 C 、 V←Rn
TEQ Rn, operand2 相等测试指令 TEQ{cond}
^ operand2

注意: TEQ 指令与 EORS 指令的区别在于 TEQ 指令不保存运算结果。使


用 TEQ 进行相等测试时,常与 EQ 、 NE 条件码配合使用。当两个数据相
等时, EQ 有效;否则 NE 有效。
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集——乘法指令

ARM 具有三种乘法指令,分别为:
32×32 位乘法指令;

32× 32 位乘加指令;

32× 32 位结果为 64 位的乘 /乘加指令。


• ARM 指令——乘法指令
•乘法指令编码

Opcode 乘 法 指 令 操
作码 Rm 为被乘数寄存器

指令执行的条件码 opcode 操作码功能表


Rs 为乘数寄存器
操作码 指令助记符 说明
S 设置条件码,与指 000 MUL Rd/RdLo 为 MLA 指 令
32 位乘法指令
令中的 S 位对应 001 MLA 相 加 的32寄 存 器 或 64 位
位乘加指令

Rn/RdHi 为目标寄存 100 UMULL 乘法指令的目标寄存器


64 位无符号乘法指令

器或 64 位乘法指令 101 UMLAL (低64 位)


32位无符号乘加指令
的目标寄存器(高 110 SMULL 64 位有符号乘法指令

32 位) 111 SMLAL 64 位有符号乘加指令


• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
(RdLo,RdHi) {S}
• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
32 位乘法指令—— MUL 指令将 和 Rs 中的值相乘,结果的低
Rm(RdLo,RdHi) {S} 32
位保存到 Rd 中。指令格式如下:
MUL{cond}{S} Rd,Rm,Rs
应用示例:
MUL R1,R2,R3 ;R1=R2×R3
MULS R0,R3,R7 ;R0=R3×R7 ,同时影响 CPSR 中的 N 位和 Z

• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
32 位乘加指令—— MLA 指令将 和 Rs 中的值相乘,再将乘积加上
Rm(RdLo,RdHi) {S}
第 3 个操作数,结果的低 32 位保存到 Rd 中。指令格式如下:
MLA{cond}{S} Rd,Rm,Rs,Rn
应用示例:
MLA R1,R2,R3,R0 ; R1=R2×R3+R0
• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
64 位无符号乘法指令—— 指令将 Rm 和 Rs 中的值作无符号
UMULL (RdLo,RdHi) {S}
数相乘,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中。指令
格式如下:
UMULL{cond}{S} RdLo,RdHi,Rm,Rs
应用示例:
UMULL R0,R1,R5,R8 ; (R1 、 R0)=R5×R8
• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
64 位无符号乘加指令—— 指令将 Rm 和 Rs 中的值作无符号
UMLAL (RdLo,RdHi) {S}
数相乘, 64 位乘积与 RdHi 、 RdLo 相加,结果的低 32 位保存到 RdLo 中
,而高 32 位保存到 RdHi 中。指令格式如下:
UMLAL{cond}{S} RdLo,RdHi,Rm,Rs
应用示例:
UMLAL R0,R1,R5,R8 ;(R1 、 R0)=R5×R8+(R1 、 R0)
• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
64 位有符号乘法指令—— 指令将 Rm 和 Rs 中的值作有符号
SMULL (RdLo,RdHi) {S}
数相乘,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中。指令
格式如下:
SMULL{cond}{S} RdLo,RdHi,Rm,Rs
应用示例:
SMULL R2,R3,R7,R6 ; (R3 、 R2)=R7×R6
• ARM 指令——乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL{cond}
UMULL RdLo,RdHi,Rm,Rs 64 位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ UMLAL{cond}
UMLAL RdLo,RdHi,Rm,Rs 64 位无符号乘加指令
(RdLo,RdHi) {S}
SMULL{cond}
SMULL RdLo,RdHi,Rm,Rs 64 位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
{S}
(RdLo,RdHi) ←Rm*Rs+ SMLAL{cond}
SMLAL RdLo,RdHi,Rm,Rs 64 位有符号乘加指令
64 位有符号乘加指令—— 指令将 Rm 和 Rs 中的值作有符号
SMLAL (RdLo,RdHi) {S}
数相乘, 64 位乘积与 RdHi 、 RdLo 相加,结果的低 32 位保存到 RdLo 中
,而高 32 位保存到 RdHi 中。指令格式如下:
SMLAL{cond}{S} RdLo,RdHi,Rm,Rs
应用示例:
SMLAL R2,R3,R7,R6 ; (R3 、 R2)=R7×R6+(R3 、 R2)
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集——分支指令

在 ARM 中有两种方式可以实现程序的跳转,
一种是使用分支指令直接跳转,另一种则是直接向
PC 寄存器赋值实现跳转。 分支指令有以下三种:
分支指令 B ;

带链接的分支指令 BL ;

带状态切换的分支指令 BX 。
• ARM 分支指令——指令编码
•分支指令 B/BL 指令编码格式

指令执行的条件码 L 区别 B 指令( L 为 24 位 有 符 号 立 即 数
0 ) 和 BL 指 令 ( L (偏移量)
为1)
•分支指令 BX 指令编码格式

指令执行的条件码 Rm 目标地址寄存器,
该寄存器装载跳转地址
• ARM 指令——分支指令
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4 , PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label ,切换处理器状态 BX{cond}
• ARM 指令——分支指令
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4 , PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label ,切换处理器状态 BX{cond}

分支指令—— B 指令,该指令跳转范围限制在当前指令的 ±32M 字节


地址内 (ARM 指令为字对齐,最低 2 位地址固定为 0) 。指令格式如下:
B{cond} Label
应用示例:
B WAITA ; 跳转到 WAITA 标号处
B 0x1234 ; 跳转到绝对地址 0x1234 处
• ARM 指令——分支指令
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4 , PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label ,切换处理器状态 BX{cond}

带链接的分支指令—— BL 指令适用于子程序调用,使用该指令后,
下一条指令的地址被拷贝到 R14( 即 LR) 连接寄存器中,然后跳转到指定
地址运行程序。跳转范围限制在当前指令的 ±32M 字节地址内。指令格式
如下:
BL{cond} Label
2. 程序跳转到目标地址
1. 当程序执行到 BL 跳转
Label 继续执行,当子程
指令时,硬件将下一条指 Addr1 BL Label Label
Addr1
Addr2
xxx PC
序执行结束后,将
令的地址 Addr2 装入 寄
LRLR Addr2 xxx Addr2
xxx LR
存器内容存入 PC ,返回
寄存器,并把跳转地址装
调用函数继续执行
入程序计数器( PC ) Label xxx
xxx
MOV PC,LR
• ARM 指令——分支指令
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4 , PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label ,切换处理器状态 BX{cond}

带状态切换的分支指令—— BX 指令,该指令可以根据跳转地址
( Rm )的最低位来切换处理器状态。其跳转范围限制在当前指令的
±32M 字节地址内 (ARM 指令为字对齐,最低 2 位地址固定为 0) 。指令格
式如下:
BX{cond} Rm
跳转后
跳转地址
Rm[0] CPSR 标志 T 位 处理器状态

0 0 ARM
1 1 Thumb
• ARM 指令——分支指令
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4 , PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label ,切换处理器状态 BX{cond}

应用示例:
ADRL R0,ThumbFun+1 ;将 Thumb 程序的入口地址加 1 存入
R0
BX R0 ; 跳转到 R0 指定的地址,
;并根据 R0 的最低位来切换处理器
状态
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集——协处理器指令

ARM 内核支持协处理器操作,协处理器的控
制要通过协处理器命令实现。
ARM 内核与协处理器的关系

数据地址总线

ARM 内核 协处理器 A 协处理器 B …

握手信号
• ARM 指令——协处理器指令
助记符 说明 操作 条件码位置
CDP
coproc,opcode1,CRd,CRn, 协处理器数据操作指令 取决于协处理器 CDP{cond}
CRm{,opcode2}
LDC{cond}
LDC{L} coproc, CRd,< 地 址 > 协处理器数据读取指令 取决于协处理器
{L}
STC{cond}
STC{L} coproc, CRd,< 地址 > 协处理器数据写入指令 取决于协处理器
{L}
MCR coproc,opcode1,Rd,CRn, ARM 寄存器到协处理器寄
取决于协处理器 MCR{cond}
CRm{,opcode2} 存器的数据传送指令

MRC coproc,opcode1,Rd,CRn, 协处理器寄存器到 ARM


寄存器到的数据传 送指 取决于协处理器 MCR{cond}
CRm{,opcode2} 令
• ARM 协处理器指令——数据操作指令
ARM 处理器通过 CDP 指令通知 ARM 协处理器执行特定的操作。该
操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使
用取决于协处理器。若协处理器不能成功地执行该操作,将产生未定义指
令异常中断。指令格式如下:
作为目标寄存器的协处 存放第 1 个源操作数
CDP{cond} coproc,opcode1,CRd,CRn,CRm{,opcode2}
的协处理器寄存器
理器寄存器
协处理器的特定操作码 存放第 2 个源操作数
的协处理器寄存器
指令操作的协处理器名
可选的协处理器特定
指令执行的条件码 操作码

CDP{cond} coproc,opcode1,CRd,CRn,CRm{,opcode2}

数据操作指令编码
• ARM 协处理器指令——数据操作指令
ARM 处理器通过 CDP 指令通知 ARM 协处理器执行特定的操作。该
操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使
用取决于协处理器。若协处理器不能成功地执行该操作,将产生未定义指
令异常中断。指令格式如下:
应用示例:
CDP p7,0,c0,c2,c3,0 ;对协处理器 7 操作,操作码为 0

;可选操作码为 0
CDP p6,1,c3,c4,c5 ;对协处理器 6 操作,操作码为 1

CDP{cond} coproc,opcode1,CRd,CRn,CRm{,opcode2}
• ARM 协处理器指令——数据存取指令
协处理器数据存取指令 LDC/STC 指令可以将某一连续内存单元的数
据读取到协处理器的寄存器中,或者将协处理器的寄存器数据写入到某一
连续的内存单元中,传送的字数由协处理器来控制。若协处理器不能成功
地执行该操作,将产生未定义指令异常中断。

数据读取指令格式
LDC{cond}{L} coproc, CRd,< 地址 >

数据存储指令格式
STC{cond}{L} coproc, CRd,< 地址 >
• ARM 协处理器指令——数据存取指令
协处理器数据存取指令 LDC/STC 指令可以将某一连续内存单元的数
据读取到协处理器的寄存器中,或者将协处理器的寄存器数据写入到某一
连续的内存单元中,传送的字数由协处理器来控制。若协处理器不能成功
地执行该操作,将产生未定义指令异常中断。
W 表示回写

P 表示前 /后变址 8 位立即数偏移


数据操作指令编码

指令执行的条件码 协处理器编号

U 表示加 /减 协处理器中的目标
寄存器
N 表示数据大小
基址寄存器
L 表示该 指令是 读
取(为 0 )还是写
入(为 1 )
• ARM 协处理器指令——数据存取指令
协处理器数据存取指令 LDC/STC 指令可以将某一连续内存单元的数
据读取到协处理器的寄存器中,或者将协处理器的寄存器数据写入到某一
连续的内存单元中,传送的字数由协处理器来控制。若协处理器不能成功
地执行该操作,将产生未定义指令异常中断。

数据操作指令编码

应用示例:
LDC p5,c2,[R2,#4] ;读取 R2+4 指向的内存单元的数据,
;传送到协处理器 p5 的 c2 寄存
器中
STC p5,c1,[R0] ;将协处理器 p5 的 C1 寄存器内数据
;传送到 R0 指向的内存单元
• ARM 协处理器指令——寄存器传送指令
如果需要在 ARM 处理器中的寄存器与协处理器中的寄存器之间进行
数据传送,那么可以使用 MCR/MRC 指令。 MCR 指令用于将 ARM 处理
器的寄存器中的数据传送到协处理器的寄存器。 MRC 指令用于将协处理
器的寄存器中的数据传送到 ARM 处理器的寄存器中。若协处理器不能成
功地执行该操作,将产生未定义指令异常中断。

MCR 指令格式( ARM 协处理器)


MCR{cond} coproc,opcode1,Rd,CRn,CRm{,opcode2}

MRC 指令格式(协处理器 ARM )


MRC{cond} coproc,opcode1,Rd,CRn,CRm{,opcode2}
• ARM 协处理器指令——寄存器传送指令
如果需要在 ARM 处理器中的寄存器与协处理器中的寄存器之间进行
数据传送,那么可以使用 MCR/MRC 指令。 MCR 指令用于将 ARM 处理
器的寄存器中的数据传送到协处理器的寄存器。 MRC 指令用于将协处理
器的寄存器中的数据传送到 ARM 处理器的寄存器中。若协处理器不能成
功地执行该操作,将产生未定义指令异常中断。
指令执行的条件码 协处理器编号
寄存器传送指令编码

表示协处理器特定操 存放第 2 个操作数


作码 的协处理器寄存器
L 表示数据是传入 可选的协处理器特
ARM ( 为 0 ) 还 是 定操作码
传入协处理器(为
1) 在 ARM 中 的 寄 存
存放第 1 个操作数的 器
协处理器寄存器
• ARM 协处理器指令——寄存器传送指令
如果需要在 ARM 处理器中的寄存器与协处理器中的寄存器之间进行
数据传送,那么可以使用 MCR/MRC 指令。 MCR 指令用于将 ARM 处理
器的寄存器中的数据传送到协处理器的寄存器。 MRC 指令用于将协处理
器的寄存器中的数据传送到 ARM 处理器的寄存器中。若协处理器不能成
功地执行该操作,将产生未定义指令异常中断。

寄存器传送指令编码

应用示例:
MCR p6,2,R7,c1,c2 ;将 ARM 中的 R7 寄存器内容传

; 到协处理器 6 的 C1 和 C2 寄存

MRC p5,2,R2,c3,c2 ;将协处理器 5 的 C3 和 C2 寄存
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 指令集——杂项指令

ARM 指令集中有三条指令作为杂项指令,实
际上这三条指令非常重要。它们如下所示:
助记符 说明 操作 条件码位置
SWI immed_24 软中断指令 产生软中断,处理器进入管理模式 SWI{cond}
MRS Rd,psr 读状态寄存器指令 Rd←psr , psr 为 CPSR 或 SPSR MRS{cond}
psr_fields←Rd/#immed_8r , psr
MSR psr_fields,
写状态寄存器指令 为 MSR{cond}
Rd/#immed_8r
CPSR 或 SPSR
• ARM 杂项指令——软中断指令
SWI 指令用于产生软中断,从而实现从用户模式变换到管理模式,并
且将 CPSR 保存到管理模式的 SPSR 中,然后程序跳转到 SWI 异常入口。
在其它模式下也可使用 SWI 指令,处理器同样地切换到管理模式。
该指令主要用于用户程序调用操作系统的系统服务,操作系统在
SWI 异常处理程序中进行相应的系统服务。

SWI 指令格式
SWI{cond} immed_24

SWI 指令编码

指令执行的条件码 指 令 传 递 的 参 数 ( 24 位 立 即
数)
• ARM 杂项指令——软中断指令
根据 SWI 指令传递的参数, SWI 异常处理程序可以作出相应的处理。
SWI 指令传递参数有以下两种方法,
指令中的 24 位立即数指定了用户请求的服务类型,参数通过通用寄
存器传递。
MOV R0,#34 ;设置子功能号为 34
SWI 12 ;调用 12 号软中断
指令中的 24 位立即数被忽略,用户请求的服务类型由寄存器 R0 的值
决定,参数通过其它的通用寄存器传递。
MOV R0,#12 ;调用 12 号软中断
MOV R1,#34 ;设置子功能号为 34
SWI 0
• ARM 杂项指令——软中断指令
在 SWI 异常中断处理程序中,取出 SWI 指令中立即数的步骤为:
首先确定引起软中断的 SWI 指令是 ARM 指令还是 Thumb 指令,这
可通过对 SPSR 访问得到;
然后取得该 SWI 指令的地址,这可通过访问 LR 寄存器得到;

接着读出该 SWI 指令,分解出立即数。


SWI_Handler
STMFD SP!, {R0-R3, R12, LR} ; 现场保护
MRS R0, SPSR ; 读取 SPSR
STMFD SP!, {R0} ; 保存 SPSR
TST R0, #0x20 ; 测试 T 标志位
LDRNEH R0, [LR,#-2] ; 若是 Thumb 指令,读取指令码 (16
位)
BICNE R0, R0, #0xFF00 ; 取得 Thumb 指令的 8 位立即数
LDREQ R0, [LR,#-4] ; 若是 ARM 指令,读取指令码 (32 位 )
BICEQ R0, R0, #0xFF000000 ; 取得 ARM 指令的 24 位立即数
...
• ARM 杂项指令——状态寄存器读指令
在 ARM 处理器中,只有 MRS 指令可以对状态寄存器 CPSR 和 SPSR
进行读操作。通过读 CPSR 可以了解当前处理器的工作状态。读 SPSR 寄
存器可以了解到进入异常前的处理器状态。

MRS 指令格式
MRS{cond} Rd,psr

指令对应编码

指令执行的条件码 区 别 CPSR ( 为 目标寄存器,不能


0 ) 和 SPSR ( 为 为 R15
1 )寄存器
• ARM 杂项指令——状态寄存器读指令

应用示例:
MRS R1,CPSR ; 将 CPSR 状态寄存器读取,保存到 R1

MRS R2,SPSR ; 将 SPSR 状态寄存器读取,保存到 R2

• ARM 杂项指令——状态寄存器写指令
在 ARM 处理器中,只有 MSR 指令可以对状态寄存器 CPSR 和 SPSR
进行写操作。与 MRS 配合使用,可以实现对 CPSR 或 SPSR 寄存器的读 -
修改 -写操作,可以切换处理器模式、或者允许 /禁止 IRQ/FIQ 中断等。

MSR 指令格式 1 MSR{cond} psr_fields,#immed_8r

MSR 指令格式 2 MSR{cond} psr_fields,Rm

指令执行的条件码

CPSR 或 SPSR
指定传送的区域,可以为以下字母 保存要传送到状态 要传送到状态寄存
(必须小写)的一个或者组合: 寄存器指定域数据 器指定域的立即数
的源寄存器
c 控制域屏蔽字节 (psr[7..0])
x 扩展域屏蔽字节 (psr[15..8])
s 状态域屏蔽字节 (psr[23..16])
f 标志域屏蔽字节 (psr[31..24])
• ARM 杂项指令——状态寄存器写指令
在 ARM 处理器中,只有 MSR 指令可以对状态寄存器 CPSR 和 SPSR
进行写操作。与 MRS 配合使用,可以实现对 CPSR 或 SPSR 寄存器的读 -
修改 -写操作,可以切换处理器模式、或者允许 /禁止 IRQ/FIQ 中断等。

MSR 指令 1 编码

MSR 指令 2 编码

指令执行的条件码

CPSR 或 SPSR
指定传送的区域,可以为以下字母 Rotate :
保存要传送到状态 要传送到状态寄存
(必须小写)的一个或者组合: 寄存器指定域数据
立即数对齐 器指定域的立即数
的源寄存器
c 控制域屏蔽字节 (psr[7..0]) 8_bit_immediate :
8 位立即数
x 扩展域屏蔽字节 (psr[15..8])
s 状态域屏蔽字节 (psr[23..16])
f 标志域屏蔽字节 (psr[31..24])
• ARM 杂项指令——状态寄存器写指令

应用示例 1 : 应用示例 2 :
;子程序:使能 IRQ 中断 ;子程序:禁止 IRQ 中断
ENABLE_IRQ DISABLE_IRQ
MRS R0, CPSR MRS R0 CPSR (1)
BIC R0, R0,#0x80 ORR R0, R0,#0x80 (2)
MSR CPSR_c,R0 MSR CPSR_c,R0 (3)
MOV PC,LR MOV PC,LR (4)

1. 将 CPSR 寄存器内容读出到 R0 3. 将修改后的值写回 CPSR 寄存



2. 修改对应于 CPSR 中的 I控制位 器的对应控制域;
; 4. 返回上一层函数;
ARM 指令小节目录
1. 指令格式
2. 条件码
3. 存储器访问指令
4. 数据处理指令
5. 乘法指令
6.ARM 分支指令
7. 协处理器指令
8. 杂项指令
9. 伪指令
2 指令集介绍
 ARM 伪指令
ARM 伪指令不属于 ARM 指令集中的指令,
是为了编程方便而定义的。
伪指令可以像其它 ARM 指令一样使用
,但在编译时这些指令将被等效的 ARM 指令代
替。
ARM 伪指令有四条,分别为:
ADR 伪指令、
ADRL 伪指令、
LDR 伪指令、
NOP 伪指令。
• ARM 伪指令——小范围的地址读取
ADR 伪指令将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地
址值读取到寄存器中。在汇编编译器编译源程序时, ADR 伪指令被编译
器替换成一条合适的指令。通常,编译器用一条 ADD 指令或 SUB 指令来
实现该 ADR 伪指令的功能,若不能用一条指令实现,则产生错误,编译
失败。
ADR 伪指令格式
ADR{cond} register,expr

指令执行的条件码 加载的目标寄存器 地址表达式

地址表达式 expr 的取指范围:


当地址值不是字对齐时,其取指范围为 -255B ~ 255B ;

当地址值是字对齐时,其取指范围为 -1020B ~ 1020B


• ARM 伪指令——小范围的地址读取

应用示例(源程序): 编译后的反汇编代码:

... ...
ADR R0,Delay 0x20 ADD r1,pc,#0x3c
... ...
Delay ...
MOV R0,r14 0x64 MOV r0,r14
... ...

使用伪指令将程序标号 地址 程序代码
Delay 的地址存入 R0
• ARM 伪指令——小范围的地址读取

应用示例(源程序): 编译后的反汇编代码:

... ...
ADR R0,Delay 0x20 ADD r1,pc,#0x3c
... ...
Delay ...
MOV R0,r14 0x64 MOV r0,r14
... ...

使用伪指令将程序标号
Delay 的地址存入 R0 ADR 伪指令被汇编成一条指令
• ARM 伪指令——小范围的地址读取

应用示例 2 (查表):

ADR R0,DISP_TAB ; 加载转换表地址


LDRB R1,[R0,R2] ; 使用 R2 作为参数,进行查表

DISP_TAB
DCB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8
• ARM 伪指令——中等范围的地址读取
ADRL 伪指令将基于 PC 相对偏移的地址值或基于寄存器相对偏移的
地址值读取到寄存器中,比 ADR 伪指令可以读取更大范围的地址 。
在汇编编译器编译源程序时, ADRL 伪指令被编译器替换成两条
合适的指令。若不能用两条指令实现,则产生错误,编译失败。
ADRL 伪指令格式
ADRL{cond} register,expr

指令执行的条件码 加载的目标寄存器 地址表达式

地址表达式 expr 的取指范围:


当地址值不是字对齐时,其取指范围为 -64K ~ 64K ;

当地址值是字对齐时,其取指范围为 -256K ~ 256K ;


• ARM 伪指令——中等范围的地址读取

应用示例(源程序):
...
ADRL R0,Delay
使用伪指令将程序标号
... Delay 的地址存入 R0
Delay
MOV R0,r14
...
• ARM 伪指令——大范围的地址读取
LDR 伪指令用于加载 32 位的立即数或一个地址值到指定寄存
器。
在汇编编译源程序时, LDR 伪指令被编译器替换成一
条合适的指令。若加载的常数未超出 MOV 或 MVN 的范围,则
使用 MOV 或 MVN 指令代替该 LDR 伪指令,否则汇编器将常
量放入文字池,并使用一条程序相对偏移的 LDR 指令从文字池
读出常量。 LDR 伪指令格式

LDR{cond} register,=expr

指令执行的条件码 加载的目标寄存器 基于 PC 的地址表达式


或外部表达式
• ARM 伪指令——大范围的地址读取
应用示例(源程序):

...
LDR R1,=InitStack
... 使用伪指令将程序标号
InitStack 的地址存入 R1
InitStack
MOV R0, LR
...
将超过 MOV 和 MVN
...
可操作范围的数
LDR R1,=0XFFF (即无效立即数),
装入寄存器 R1.
• ARM 伪指令——大范围的地址读取

应用示例(源程序):

编译后的反汇编代码:
...
LDR R1,=InitStack ...

InitStack 0x60 LDR R1,0xb4


0x64 MOV R0, LR
MOV R0, LR
...
...
0xb4 DCD 0x64

使用伪指令将程序标号 地址 程序代码
InitStack 的地址存入 R1
• ARM 伪指令——大范围的地址读取

应用示例(源程序): 编译后的反汇编代码:
... ...
LDR R1,=InitStack 0x60 LDR R1,0xb4
... ...
InitStack 0x64 MOV R0, LR
MOV R0, LR ...
... 0xb4 DCD 0x64

使用伪指令将程序标号 LDR 伪指令被汇编成一条 LDR 指令


InitStack 的地址存入 R1 ,并在文字池中定义了一个常量,
该常量为 InitStack 标号的地址
• ARM 伪指令——大范围的地址读取

注意:
1. 从指令位置到文字池的偏移量必须小于 4KB ;
2. 与 ARM 指 令 的 LDR 相 比 , 伪 指 令 的 LDR 的 参 数
有“ =” 号。
• ARM 伪指令——空操作伪指令

NOP 伪指令在汇编时将会被代替成 ARM 中的空操作,比如可能


是“ MOV R0,R0” 指令等。 NOP 可用于延时操作。

应用示例(延时子程序)

Delay
NOP ;空操作
NOP
NOP
SUBS R1,R1,#1 ;循环次数减一
BNE Delay ;如果循环没有结束,跳转 Delay 继

MOV PC,LR ;子程序返回
3 Thumb 指令集介绍
 Thumb 指令

Thumb 指令集可以看作是 ARM 指令压缩形式


的子集,它是为减小代码量而提出的,具有 16 位
的代码密度。 Thumb 指令体系不完整,只支持通用
功能。必要时仍需要使用 ARM 指令,如进入异常
时。
说明: Thumb 指令的格式与使用方式与 ARM 指令集类似,而
且使用并不是很频繁,建议这部分内容选修。
 简单的 Thumb 程序
; 功能:使用 BX 指令切换处理器状态
AREA Example8,CODE,READONLY
ENTRY
CODE32
ARM_CODE
ADR R0,THUMB_CODE+1
BX R0 ; 跳转并切换处理器状态
 
在 Thumb 程序段之前要
CODE16 用 CODE16 声明。
THUMB_CODE
MOV R0,#10 ; R0 = 10
MOV R1,#20 ; R1 = 20
ADD R0,R1 ; R0 = R0+R1
B .
END
Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
 Thumb 指令集与 ARM 指令集的区别

Thumb 指令集较 ARM 指令集有如下限制:


只有 B 指令可以条件执行,其它指令都不能条件执行;

分支指令的跳转范围有更多限制;

数据处理指令的操作结果必须放入其中一个;

单寄存器访问指令,只能操作 R0 ~ R7 ;

LDM 和 STM 指令可以对 R0 ~ R7 的任何子集进行操


作;
Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
 Thumb 存储器访问指令

•LDR 和 STR—— 单寄存器加载 /存储指令


LDMIA 和 STMIA—— 多寄存器加载 /存储指令
•PUSH 和 POP—— 寄存器入栈及出栈指令
 Thumb 存储器访问指令
单寄存器访问指令

助记符 说明 操作 影响标志
Rd←[Rn,#immed_5×4]
LDR/STR Rd,addressing 加载 / 存储字数据 无
, Rd 、 Rn 为 R0 ~ R7
加载 / 存储无符号半 Rd←[Rn,#immed_5×2]
LDRH/STRH Rd,addressing 无
字数据 , Rd 、 Rn 为 R0 ~ R7
LDRB/STRB 加载 / 存储无符号字 Rd←[Rn,#immed_5×1]

Rd,addressing 节数据 , Rd 、 Rn 为 R0 ~ R7
Rd←[Rn,Rm] , Rd 、 Rn
LDRSH Rd,addressing 加载有符号半字数据 无
、 Rm 为 R0 ~ R7
Rd←[Rn,Rm] , Rd 、 Rn
LDRSB Rd,addressing 加载有符号字节数据 无
、 Rm 为 R0 ~ R7

注:寄存器必须为 R0 ~ R7 。
 Thumb 存储器访问指令

•LDMIA 和 STMIA—— 多寄存器加载 /存储指令


可以实现在一组寄存器和一块连续的内存
单元之间传输数据。 LDMIA 为加载多个寄存器;
STMIA 为存储多个寄存器。使用它们允许一条指令
传送 8 个低寄存器 R0 ~ R7 的任何子集。
• 多寄存器加载 / 存储指令
指令格式
LDMIA Rn!,reglist
STMIA Rn!,reglist
其中: Rn 加载 / 存储的起始地址寄存器。 Rn 必须为 R0 ~ R7 。
reglist 加载 / 存储的寄存器列表。寄存器必须为 R0 ~ R7 。

指令编码

L 用于区别加载( L 为
1 )还是存储( L 为
0)
应用示例:
LDMIA R0!,{R2-R7} ;加载 R0 指向的地址上的多字数据,
;保存到 R2 ~ R7 中, R0 的值更新。
STMIA R1!,{R2-R7} ;将 R2 ~ R7 的数据存储到 R1 指向的
;地址上, R1 值更新
 Thumb 存储器访问指令

•PUSH 和 POP—— 寄存器入栈及出栈指令


实现低寄存器和可选的 LR 寄存器入栈及
低寄存器和可选的 PC 寄存器出栈操作。堆栈地址
由 SP 寄存器设置,堆栈是满递减堆栈。
• 寄存器入栈及出栈指令
指令格式
PUSH {reglist[,LR]}
POP {reglist[,PC]}
其中: reglist 入栈 / 出栈低寄存器列表,即 R0 ~ R7 。
LR 入栈时的可选寄存器。
PC 出栈时的可选寄存器。

指令编码

L 用于区别出栈( L 为 R 用于区别操作寄存器
1 )或入栈( L 为 0 ) 中是否有 LR/PC 寄存器
(有则 R 为 1 ,否则为
0)
• 寄存器入栈及出栈指令
指令格式
PUSH {reglist[,LR]}
POP {reglist[,PC]}
其中: reglist 入栈 / 出栈低寄存器列表,即 R0 ~ R7 。
LR 入栈时的可选寄存器。
PC 出栈时的可选寄存器。

应用示例:
PUSH {R0-R7,LR} ;将低寄存器 R0 ~ R7 全部入栈

;LR 也入栈
POP {R0-R7,PC} ;将堆栈中的数据弹出到
;低寄存器 R0 ~ R7 及 PC 中
Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
 Thumb 数据处理指令

Thumb 数据处理指令涵盖了编译器需要的大多
数操作。大部分的 Thumb 数据处理指令采用 2 地址
格式,不能在单指令中同时完成一个操作数的移位
及一个 ALU 操作。所以数据处理操作比 ARM 状态
的更少,并且访问寄存器 R8 ~ R15 受到限制。数
据处理指令分为两类:
数据传送指令

算术逻辑运算指令
 Thumb 数据处理指令——数据传送指令

助记符 操作 影响标志
MOV Rd,#expr Rd←expr , Rd 为 R0 ~ R7 影响 N 、 Z
Rd 和 Rm 均为 R0 ~ R7 时
Rd←Rm , Rd 、 Rm 均可为 R0 ~
MOV Rd,Rm ,影响 N 、 Z ,清零 C
R15
、V
Rd←(~Rm) , Rd 、 Rm 均为 R0 ~
MVN Rd,Rm 影响 N 、 Z
R7
Rd←(-Rm) , Rd 、 Rm 均为 R0 ~
NEG Rd,Rm 影响 N 、 Z 、 C 、 V
R7
• 数据传送指令—— MOV
MOV 指令将 8 位立即数或寄存器传送到目标寄存器中。
其指令格式如下:
MOV Rd,#expr
MOV Rd,Rm
其中: Rd 目标寄存器。 MOV Rd,#expr 时, Rd 必须在 R0 ~ R7 之间。
exper 8 位立即数,即 0 ~ 255 。
Rm 源寄存器。为 R0 ~ R15 。

指令编码(立即数传送)

指令编码(寄存器传送)
• 数据传送指令—— MOV
注意:
“MOV Rd,#expr” 指令会更新 N 和 Z 标志,对标志 C 和 V 无影响。
“MOV Rd,Rm” 指令,若 Rd 或 Rm 是高寄存器( R8 ~ R15 ),则标
志不受影响,若 Rd 或 Rm 都是低寄存器( R0 ~ R7 ),则更新标志 N 和
Z ,且清除标志 C 和 V 。

应用示例:
MOV R1,#0x10 ; R1=0x10
MOV R0,R8 ; R0=R8
MOV PC,LR ; PC=LR ,子程序返回
• 数据传送指令—— MVN
MVN 指令将寄存器 Rm 按位取反后传送到目标寄存器
Rd 中。指令的执行会更新 N 和 Z 标志,对标志 C 和 V 无影
响。其指令格式如下:

MVN Rd,Rm
其中: Rd 目标寄存器。 MOV Rd,#expr 时, Rd 必须在 R0 ~ R7 之间。
Rm 源寄存器。为 R0 ~ R15 。

指令编码
• 数据传送指令—— MVN
MVN 指令将寄存器 Rm 按位取反后传送到目标寄存器
Rd 中。指令的执行会更新 N 和 Z 标志,对标志 C 和 V 无影
响。其指令格式如下:

MVN Rd,Rm
其中: Rd 目标寄存器,必须在 R0 ~ R7 之间。
Rm 源寄存器,必须在 R0 ~ R7 之间。

应用示例:
MVN R1,R2 ; 将 R2 取反,结果存于 R1
• 数据传送指令—— NEG
NEG 指令将寄存器 Rm 乘以 -1 后传送到目标寄存器 Rd
中。指令会更新 N 、 Z 、 C 和 V 标志。其指令格式如下:
NEG Rd,Rm
其中: Rd 目标寄存器,必须在 R0 ~ R7 之间。
Rm 源寄存器。为 R0 ~ R7 。

指令编码
• 数据传送指令—— NEG
NEG 指令将寄存器 Rm 乘以 -1 后传送到目标寄存器 Rd
中。指令会更新 N 、 Z 、 C 和 V 标志。其指令格式如下:
NEG Rd,Rm
其中: Rd 目标寄存器,必须在 R0 ~ R7 之间。
Rm 源寄存器。为 R0 ~ R7 。

应用示例:
NEG R1,R0 ; R1=-R0
 Thumb 数据处理指令——算术逻辑运算指令

算术逻辑指令包括以下几类:
算术指令

逻辑运算指令

移位指令

比较指令
• 算术运算指令—— ADD
ADD 指令将两个数据相加,结果保存到 Rd 寄存器中
。 低寄存器的 ADD 指令格式:
ADD Rd,Rn,Rm
ADD Rd,Rn,#expr3
ADD Rd,#expr8
其中: Rd 目标寄存器,必须在 R0 ~ R7 之间。
Rn 第 1 个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。
exper 3 位立即数,即 0 ~ 7 。
expr8 8 位立即数,即 0 ~ 255 。

应用示例:
ADD R2,R1,R0 ; R2=R0+R1
ADD R2,R1,#7 ; R2=R1+7
ADD R1,#200 ; R1=R1+200
• 算术运算指令—— ADD
ADD 指令将两个数据相加,结果保存到 Rd 寄存器中

高或低寄存器的 ADD 指令格式:
ADD Rd,Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器。
Rm 第 2 个操作数寄存器。
Rd 和 Rm 可以是 R0-R15 中任何一个。若 Rd 和 Rm 是低寄存器,则更新条件码。

应用示例:
ADD R1,R10 ; R1=R1+R10
• 算术运算指令—— SUB
SUB 指令将两个数据相减,结果保存到 Rd 寄存器中
。 低寄存器的 SUB 指令格式:
SUB Rd,Rn,Rm
SUB Rd,Rn,#expr3
SUB Rd,#expr8
其中: Rd 目标寄存器,必须在 R0 ~ R7 之间。
Rn 第 1 个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。
exper 3 位立即数,即 0 ~ 7 。
expr8 8 位立即数,即 0 ~ 255 。

应用示例:
SUB R2,R1,R0 ; R2=R1-R0
SUB R1,R2,#7 ; R2=R1-7
SUB R1,#200 ; R1=R1-200
• 算术运算指令—— SUB
SUB 指令将两个数据相减,结果保存到 Rd 寄存器中。

SP 操作的 SUB 指令格式:


SUB SP,#expr
其中: SP 目标寄存器,也是第一个操作数寄存器。
expr 立即数,在 -508 ~ +508 之间的 4 的整数倍的数。

应用示例:
SUB SP,#-380 ;SP=SP-380
• 算术运算指令—— ADC
ADC 指令将 Rm 的值相加,再加上 CPSR 中的
C 条件标志位,结果保存到 Rd 寄存器。
ADC 指令格式:
ADC Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例 (64 位加法 ):


ADD R0,R2
ADC R1,R3 ;(R1 、 R2)=(R1 、 R0)+(R3 、 R2)
• 算术运算指令—— SBC
SBC 指令用寄存器 Rd 减去 Rm ,再减去 CPSR
中的 C 条件标志位的非,结果保存到 Rd 寄存器。
SBC 指令格式:
SBC Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例 (64 位减法 ):


SUB R0,R2
SBC R1,R3 ;(R1 、 R2)=(R1 、 R0)-(R3 、 R2)
• 算术运算指令—— MUL
MUL 乘法指令用寄存器 Rd 乘以 Rm ,结果保
存到 Rd 寄存器。
MUL 指令格式:
MUL Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例
MUL R0,R1 ;R0=R0×R1
• 逻辑运算指令—— AND
AND 指令将寄存器 Rd 的值与寄存器 Rm 的值
按位作逻辑“与”操作,结果保存到 Rd 寄存器中

AND 指令格式:
ADD Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例:
MOV R1,#0x0F
AND R0,R1 ; R0=R0 & R1 ,清零 R0 高 24 位
• 逻辑运算指令—— ORR
ORR 指令将寄存器 Rd 的值与寄存器 Rn 的值
按位作逻辑“或”操作,结果保存到 Rd 寄存器中

ORR 指令格式:
ORR Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例:
MOV R1,#0x0F
ORR R0,R1 ; R0=R0 | R1 ,置位 R0 低 4 位
• 逻辑运算指令—— EOR
EOR 指令将寄存器 Rd 的值与寄存器 Rn 的值
按位作逻辑“异或”操作,结果保存到 Rd 寄存器
中。
EOR 指令格式:
EOR Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例:
MOV R1,#0x0F
EOR R0,R1 ; R0=R0 ^ R1 ,取反 R0 低 4 位
• 逻辑运算指令—— BIC
BIC 指令将寄存器 Rd 的值与寄存器 Rm 的值
的反码作逻辑“与”操作,结果保存到 Rd 寄存器
中。
BIC 指令格式:
BIC Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第 2 个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例:
MOV R1,#0x02
BIC R0,R1 ; 清零 R0 的第 2 位,其它位不变
• 移位指令—— ASR
ASR 指令将数据算术右移,将符号位拷贝到左
侧空出的位,移位结果保存到 Rd 寄存器中。
ASR 指令格式:
ASR Rd, Rs
ASR Rd,Rm,#expr
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。

Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间
Rm 立即数移位的源寄存器,必须在 R0 ~ R7 之间
expr 立即数移位位数,值为 1 ~ 32

ASR 移位操作:

若移位位数为 32 ,则 Rd 清零,最后移出的位保留在标志 C 中;若移


位位数大于 32 ,则 Rd 和标志 C 均被清零;若移位位数为 0 ,则不影响 C
标志。
• 移位指令—— ASR
ASR 指令将数据算术右移,将符号位拷贝到左
侧空出的位,移位结果保存到 Rd 寄存器中。
ASR 指令格式:
ASR Rd, Rs
ASR Rd,Rm,#expr
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。

Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间
Rm 立即数移位的源寄存器,必须在 R0 ~ R7 之间
expr 立即数移位位数,值为 1 ~ 32
应用示例:
ASR R1,R2
ASR R3,R1,#2
• 移位指令—— LSL
LSL 指令将数据逻辑左移,空位清零,移位结
果保存到 Rd 寄存器中。
LSL 指令格式:
LSL Rd, Rs
LSL Rd,Rm,#expr
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。

Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间
Rm 立即数移位的源寄存器,必须在 R0 ~ R7 之间
expr 立即数移位位数,值为 1 ~ 31

LSL 移位操作: 0

若移位位数为 32 ,则 Rd 清零,最后移出的位保留在标志 C 中;若移


位位数大于 32 ,则 Rd 和标志 C 均被清零;若移位位数为 0 ,则不影响 C
标志。
• 移位指令—— LSL
LSL 指令将数据逻辑左移,空位清零,移位结
果保存到 Rd 寄存器中。
LSL 指令格式:
LSL Rd, Rs
LSL Rd,Rm,#expr
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间
Rm 立即数移位的源寄存器,必须在 R0 ~ R7 之间
expr 立即数移位位数,值为 1 ~ 31

应用示例:
LSL R6,R7
LSL R1,R6,#2
• 移位指令—— LSR
LSR 指令将数据逻辑右移,空位清零,移位结
果保存到 Rd 寄存器中。
LSR 指令格式:
LSR Rd, Rs
LSR Rd,Rm,#expr
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间
Rm 立即数移位的源寄存器,必须在 R0 ~ R7 之间
expr 立即数移位位数,值为 1 ~ 32

LSR 移位操作: 0

若移位位数为 32 ,则 Rd 清零,最后移出的位保留在标志 C 中;若移


位位数大于 32 ,则 Rd 和标志 C 均被清零;若移位位数为 0 ,则不影响 C
标志。
• 移位指令—— LSR
LSR 指令将数据逻辑右移,空位清零,移位结
果保存到 Rd 寄存器中。
LSR 指令格式:
LSR Rd, Rs
LSR Rd,Rm,#expr
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间
Rm 立即数移位的源寄存器,必须在 R0 ~ R7 之间
expr 立即数移位位数,值为 1 ~ 32

应用示例:
LSR R3,R0
LSR R5,R2,#2
• 移位指令—— ROR
ROR 指令将数据循环右移,寄存器右侧移出的
位放入左侧空出的位上,移位结果保存到 Rd 寄存
器中。
ROR 指令格式:
ROR Rd, Rs
其中: Rd 目标寄存器,也是第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在 R0 ~ R7 之间

ROR 移位操作:

应用示例:
ROR R3,R0
• 比较指令—— CMP
CMP 指令使用寄存器 Rn 的值减去第二个操作
数的值,根据操作的结果更新 CPSR 中的
N 、 Z 、 C 和 V 标志位。
CMP 指令格式:
CMP Rn,#epr
其中: Rn 第一个操作数寄存器,必须在 R0 ~ R7 之间。
expr 立即数,值为 0 ~ 255
CMP Rn,Rm
其中: Rd 和 Rm 可以是 R0-R15 中任何一个。

应用示例:
CMP R1,#10 ;R1 与 10 比较,设置相关标志位
CMP R1,R2 ;R1 与 R2 比较,设置相关标志位
• 比较指令—— CMN
CMN 指令使用寄存器 Rn 的值加上寄存器 Rm
的值,根据操作的结果更新 CPSR 中的 N 、 Z 、 C
和 V 标志位。

CMN 指令格式:
CMN Rn,Rm
其中: Rd 和 Rm 可以是 R0-R15 中任何一个。

应用示例:
CMN R0,R2 ;R0 与 -R2 比较,设置相关标志位
• 比较指令—— TST
TST 指令将寄存器 Rn 的值与寄存器 Rm 的值
按位作逻辑“与”操作,根据操作的结果更新
CPSR 中的 N 、 Z 、 C 和 V 标志位。
TST 指令格式:
TST Rn,Rm
其中: Rn 第一个操作数寄存器,必须在 R0 ~ R7 之间。
Rm 第二个操作数寄存器,必须在 R0 ~ R7 之间。

应用示例:
MOV R0,#0x01
TST R1,R0 ;判断 R1 的最低位是否为 0
Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
 Thumb 分支指令

助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-2 , PC←label 无
PC←label ,切换处理器
BX Rm 带状态切换的分支指令 无
状态
• 分支指令—— B
B 指令跳转到指定的地址执行程序,它是 Thumb
指令集中的唯一有条件执行指令。如果使用了条件执行
,那么跳转范围在 -252 ~ +256 字节内。如果没有使用
条件执行,那么跳转范围在 ±2K 内。
B 指令格式:
B{cond} label
其中: label 表示程序标号。

应用示例:
B WAITB ;WAITB 标号在当前指令的 ±2K 范围内
BEQ LOOP1 ;LOOP1 标号在当前指令的 -252 ~ +256 范围内
• 分支指令—— BL
BL 指令在跳转到指定地址执行程序前,将下一条
指令的地址拷贝到 R14 链接寄存器中。
BL 指令格式:
BL label
其中: label 表示程序标号。

注意:由于 BL 指令通常需要大的地址范围,很难用 16 位指令格


式实现,为此, Thumb 采用两条这样的指令组合成 22 位半字偏移
(符号扩展为 32 位 ),使指令转移范围为 ±4MB 。

应用示例: 反汇编代码:
ADD R0,R1 [0x1809] add r1,r1,r0
BL RstInit [0xf9dcf000] bl RstInit

指令机器码
32 位长的机器码 汇编指令
• 分支指令—— BX
BX 指令是带状态切换的分支指令,跳转地址由
Rm 指定,同时根据 Rm 的最低位的值切换处理器状态
,当最低两位均为 0 时,切换到 ARM 状态。

BX 指令格式:
BX Rm
其中: Rm 保存有目标地址的寄存器。

应用示例:
ADR R0,ArmFun ;将 ARM 程序段地址存入 R0
BX R0 ;跳至 R0 指定的地址,并切换到 ARM 状

Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
• Thumb 杂项指令—— SWI
SWI 指令用于产生软中断,从而实现从用户模式变
换到管理模式, CPSR 保存到管理模式的 SPSR 中,同
时程序跳转到 SWI 向量。在系统模式下也可以使用
SWI 指令,处理器同样能切换到管理模式。(参数传递
的方法参看 ARM 指令 SWI 的使用)

SWI 指令格式:
SWI immed_8
其中: immed_8 8 位立即数,值为 0 ~ 255 之间的整数。

应用示例:
SWI 0 ;软中断,中断立即数为 0
SWI 0x55 ;软中断,中断立即数为 0x55
Thumb 指令小节目录
1.Thumb 指令集与 ARM 指令集的区别
2. 存储器访问指令
3. 数据处理指令
4. 分支指令
5. 杂项指令
6. 伪指令
• Thumb 伪指令—— ADR
ADR 伪指令将基于 PC 相对偏移的地址值读取到寄
存器中。
ADR 指令格式:
ADR register,expr
其中: register 加载的目标寄存器
expr 地址表达式。偏移量必须是正数并小于 1KB 。
expr 必须是局部定义的,不能被导入。

应用示例:
ADR R0,TxTab
... 地址范围不超过 1KB
TxTab
DCB “ARM7TDMI”,0
• Thumb 伪指令—— LDR
LDR 伪指令用于加载 32 位的立即数或一个地址值
到指定寄存器。在汇编编译源程序时, LDR 伪指令被
编译器替换成一条合适的指令。详细说明参看 ARM 伪
指令部分。
LDR 指令格式:
LDR register,=expr/label-expr
其中: register 加载的目标寄存器
expr 32 位立即数
label-expr 基于 PC 的地址表达式或外部表达式。

应用示例:
LDR R0,=0x12345678 ;加载 32 位立即数 0x123456778
LDR R0,=DATA_BUF+60 ;加载 DATA_BUF 地址 +60
... 地址范围不超过 1KB
LTORG ;声明文字池
• Thumb 伪指令—— NOP
NOP 伪指令在汇编时将被替换成一条 Thumb 空操
作的指令。比如可能为“ MOV R0,R0” 指令。 NOP 伪
指令可用于延时操作。

应用示例(延时子程序):
Delay
NOP ;空操作
NOP
NOP
SUB R1,R1,#1 ;循环次数减一
;不需要加‘ S’ 标志,就可以影响 CPSR 标
志位
BNE Delay ;如果循环没有结束,跳转 Delay 继续
MOV PC,LR ;子程序返回

You might also like