Professional Documents
Culture Documents
第2章 ARM体系结构
第2章 ARM体系结构
ARM 体系结构
2.1 ARM 体系结构简介
ARM 公司
公司的特点是只设计芯片,而不直接生产。
它将技术授权给世界上许多著名的半导体、软件
和 OEM 厂商,并提供服务。
将技术授权给
芯片厂商
...
加入适当外围电路形成
各具特色的 ARM 芯片
支持大端格式和小端格式两种存储字数据的方法;
低电源电压
ARM 微处理器包括 ARM7 、 ARM9 、 ARM11 、
Cortex-A (高性能)、 Cortex-R (实时)、
Cortex-M (低成本低功耗)、 SecurCore (安全)
等系列处理器。
典 31 个 32 位通用寄存器及 6 位状态寄存器
指令译码及控制逻辑
型
的
A
R
M
体
系 32 位 ALU
32×8 位乘法器 32×32 位桶形移位寄存器
结
构 指令流水线和数据/地址寄存器等
方
框
图
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 处理器核简介
SecurCore
ARM 处理器结构综
述
ARM 系 微处理器核 特点
列
ARM7 ARM7TDMI :整数处理核 冯诺伊曼体系结构;
ARM7TDMI 处理器的可 ARMTDMI 是目前应用最广的微处理
综合版本; 器核
ARM720T :带 MMU 的处理 ARM720T 带有 MMU 和 8KB 的指令
器核心,支持操作系统; 数据混合 cache ;
ARM7EJ-S :带有 DSP 和 ARM7EJ- 执行 ARMv5TEJ 指令, 5 级
Jazelle TM 技术,能够实 流水线,提供 Java 加速指令,没有存储
现 Java 加速功能 器保护。
31 个通用寄存器
6 个状态寄存器
2.3.1 处理器的运行模式
这样的好处是可以更好的支持操作系统并提高工作效率
处理器运行模式
处理器模式 说明 备注
用户
正常程序工作模式 不能直接切换到其它模式
(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 处理器有两种处理器状态:
( 2 )进入 ARM 状态
当操作数寄存器的状态位(位[ 0 ])为 0 时,执行 BX
指令
进入 ARM 状态。
处理器进行异常处理
跳转地址标号
; 从 Arm 状态切换到 Thumb 状态
地址最低位
LDR R0,=Lable+1
为 1 ,表示
BX R0 切换到
Thumb 状态
; 从 Thumb 状态切换到 ARM 状态
LDR R0,=Lable 地址最低位为
0 ,表示切换
BX R0 到 ARM 状态
2.3.3 处理器的寄存器组织
简介
在不同的工作模式和处理器状态下,程序员可
以访问的寄存器也不尽相同。
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 有可能发生覆盖错误。
异常发生时,程序要跳转至异常服务程序,
对返回地址的处理与子程序调用类似,都是由硬件完成的。
区别在于有些异常有一个小常量的偏移。
R14 寄存器注意要点
当发生异常嵌套时,这些异常之间可能会发生冲突。例如:
如果用户在用户模式下执行程序时发生了 IRQ 中断,用户模式
寄存器不会被破坏。
但是如果允许在 IRQ 模式下的中断处理程序重新使能 IRQ 中断
,并且发生了嵌套的 IRQ 中断时,外部中断处理程序保存在 R14_irq
中的任何值都将被嵌套中断的返回地址所覆盖。
R14 寄存器注意要点
未被破坏
R14 寄存器注意要点
未被破坏 被破坏
程序计数器 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 的限制
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 反映了当前处理器的状态,其包含:
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 通常不变。
程序状态寄存器
控制位
T 位;
模式位 M4-M0 。
程序状态寄存器
控制位
中断禁止位包括 I 和 F 位:
当 I=1 时, IRQ 中断被禁止;
T 位反映了正在操作的状态:
当 T=1 时, 处理器正在 Thumb 状态下运行;
模式位包括 M4 、 M3 、 M2 、 M1 和 M0 ,这
些位决定处理器的操作模式。
注意:不是所有模式位的组合都定义了有效的处理
器模式,如果使用了错误的设置,将引起一个无法
恢复的错误。
CPSR 模式位设置表
CPSR 中的保留位被保留将来使用。
为了提高程序的可移植性,当改变 CPSR 标志和
控制位时,请不要改变这些保留位。
另外,请确保您程序的运行不受保留位的值影响
,因为将来的处理器可能会将这些位设置为 1 或者 0 。
2.3.4 Thumb 状态寄存器
程序计数器( 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
存器
状态寄
CPSR CPSR
存器
ARM 状态和 Thumb 状态之间寄存器的关系
Thumb 状态寄存器与 ARM 状态寄存器有如下的关系
:
Thumb 状态 R0 ~ R7 与 ARM 状态 R0 ~ R7 相同
;
Thumb 状态 CPSR 与 ARM 状态 CPSR 相同;
被保存程序状态寄存器 被保存程序状态寄存器
( SP SR ) (SP SR )
在 Thumb 状态中访问高寄存器
在一个正常的程序流程执行过程中,由内部或外部源产生
的一个事件使正常的程序产生暂时的停止时,称为异常。
处理异常之前,当前处理器的状态必须保留,异常处理
完成之后,恢复保留的当前处理器状态,继续执行当前程序
。
多个异常同时发生时,处理器会按固定优先级进行处理
。
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 )复位
2. 置位 CPSR 中的 I 和 F 位(禁止 I 和 F );
当 ARM 处理器遇到一条自己和系统内任何协处理
器都无法处理的指令时,内核执行未定义指令陷阱。
软件可使用这一机制通过模拟未定义的协处理器
指令来扩展 ARM 指令集。
在模拟处理了失败的指令后,陷阱程序执行下面的指令:
MOVS PC, R14_und
恢复 PC 和 CPSR 并返回到未定义指令之后的指令。
注: MOVS 特殊指令,给 PC 赋值的同时将 SPSR 的值给 CPSR
( 3 )软件中断指令
在修复产生中止的原因后,不管处于哪种处理器操作状
态,处理程序都必须执行下面的返回指令 :
SUBS PC,R14_abt,#8
( 6 )外部中断 IRQ 请求
在一个特权模式中,可以通过置位 CPSR 中的 F 位
来禁止 FIQ 异常。
2.4.3 异常的响应过程
进入异常
1.在相应的 LR 中保存下一条指令的地址;
2.将 CPSR 复制到相应的 SPSR 中;
3. 将 CPSR 模式位强制设置为与异常类型相对应的值
;
4. 强制 PC 从相关的异常向量处取指。
图示进入异常过程
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 内核在中断异常时置位中断禁止标志,这
样可以防止不受控制的异常嵌套。
当异常结束时,异常处理程序必须:
1. 将 LR 中的值减去偏移量后存入 PC ,偏移量根据异
常的类型而有所不同;
2. 将 SPSR 的值复制回 CPSR ;
3. 清零在入口置位的中断禁止标志。
将 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” 等指令也是类
似的。
异常的入口和出口处理
如果异常处理程序已经把返回地址拷贝到堆栈
,那么可以使用一条多寄存器传送指令来恢复用户
寄存器并实现返回。
中断处理代码的开始部分和退出部分
在应用程序的设计中,异常处理采用的方式是
在异常向量表中的特定位置放置一条跳转指令
,跳转到异常处理程序。
当 ARM 处理器发生异常时,程序计数器 PC 会
被强制设置为对应的异常向量,从而跳转到异
常处理程序,当异常处理完成以后,返回到主
程序继续执行。
2.4.4 应用程序中的异常处理
中断与异常的区别
中断: CPU 对系统发生的某个事件作出的一种反
应, CPU 会暂停正在执行的程序,保留现场后自动转去
执行相应的处理程序,处理完该事件后再返回断点,继续
执行被“中断”的程序。通常与当前运行的进程无关,属
于正常现象。中断可以被屏蔽,在屏蔽解除至后,中断可
以继续得到响应和处理。
异常:是由指令执行期间所检测到的不正常的或非法的
条件引起的,与正在执行的指令有直接的联系。异常通常
不能被屏蔽,以便及时得到响应和处理。
2.5 ARM 的存储器结构
地址空间
跳转目标的计算方法:
(当前指令的地址 ) + 8 + 偏移量
下一条指令位置的计算方法:
(当前指令的地址 ) + 4
2.5 ARM 的存储器结构
存储器格式
存储器系统有两种映射机制:
小端存储器系统:
低位地址
大端模式
高位地址
0x12 0x34 0x56 0x78
在小端格式中,高位数字存放在高位字节
中。因此存储器系统字节 0 连接到数据线 7 ~ 0 。
小端模式
低位地址 高位地址
大端存储器系统:
0x78 0x56 0x34 0x12
在大端格式中,高位数字存放在低位字节
0x12345678 字数据的大小端存储方式
中。因此存储器系统字节 0 连接到数据线 31 ~ 24 。
存储器格式
注意:如果实际的存储器格式与芯片的存储器格式
不符时,只有以字为单位的数据存取才正确,否则
将出现不可预期的结果。
2.5 ARM 的存储器结构
存储器映射的 I/O
基于 ARM 内核的芯片具有许多的外设,这些外
设访问的标准方法是使用存储器映射的 I/O ,为外设
的每个寄存器都分配一个地址。通常,从这些地址
装载数据用于读入,向这些地址保存数据用于输出。
有些地址的装载和保存用于外设的控制功能,而不
是输入或输出功能。
注意:存储器映射的 I/O 位置的操作不同于正常的存
储器位置的操作。通常,存储器映射的 I/O 位置没有
高速缓存和无缓冲区。
2.6 ARM 微处理器指令系
统
简介
寻址方式是根据指令中给出的地址码字段来实现寻
找真实操作数地址的方式。 ARM 处理器具有 9 种基
本寻址方式。
1. 寄存器寻址 2. 立即寻址
3. 寄存器移位寻址 4. 寄存器间接寻址
5. 变址寻址 6. 多寄存器寻址
7. 堆栈寻址 8. 块复制(块拷贝)寻址
9. 相对寻址
2.6.1 ARM 处理器寻址方式
寻址方式分类——寄存器寻址
操作数的值在寄存器中,指令中的地址码字段指
出的是寄存器编号,指令执行时直接取出寄存器值
来操作。寄存器寻址指令举例如下:
MOV R1,R2 ; 将 R2 的值存入 R1
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 处理器寻址方式
寻址方式分类——寄存器移位寻址
寻址方式分类——寄存器间接寻址
寄存器间接寻址指令中的地址码给出的是一个通
用寄存器的编号,所需的操作数保存在寄存器指定
地址的存储单元中,即寄存器为操作数的地址指针。
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 处理器寻址方式
寻址方式分类——堆栈寻址
所以可以组合出四种类型的堆栈方式:
满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。
FD 满递减堆栈;
ED 空递减堆栈;
FA 满递增堆栈;
EA 空递增堆栈。
2.6.1 ARM 处理器寻址方式
寻址方式分类——块复制(块拷贝)寻址
多寄存器传送指令用于将一块数据从存储器
的某一位置拷贝到另一位置。 如:
STMIB LDMIB
先增 STMFA LDMED
增值
后增 STMIA LDMIA
STMEA LDMFD
LDMDB STMDB
先减 LDMEA STMFD
减值
LDMDA STMDA
后减 LDMFA STMED
2.6.1 ARM 处理器寻址方式
寻址方式分类——相对寻址
相对寻址是基址寻址的一种变通。由程序计数器 PC 提供
基准地址,指令中的地址码字段作为偏移量,两者相加后得
到的地址即为操作数的有效地址。相对寻址指令举例如下:
; 文件名: 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>}
ARM 指令的基本格式如下:
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
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>}
示例:
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 指令集——存储器访问指令
存储器访问指令分为:
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 索引
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}
多寄存器加载 /存储指令可以实现在一组寄存器和一块连续的内存单
元之间传输数据。
^ :加入该后缀后(注意:该后缀不允许在用户模式或系统模式下使用)。
( 1 )进行数据传送且寄存器列表不包含 PC 时,加载 /存储的寄存器是
用户模式下的,而不是当前模式的寄存器。
( 2 )若在 LDM 指令且寄存器列表中包含有 PC 时使用,那么除了正常的
多寄存器传送外,还将 SPSR 也拷贝到 CPSR 中,这可用于异常处理
返回。
• ARM 存储器访问指令——多寄存器存取
•LDM 和 STM—— 多寄存器加载 /存储指令编码
指令执行的条件码
进行数据复制时,先设置好源数据指针和目标指针,然后使用
块 拷 贝 寻 址 指 令
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 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)
指令执行的条件码 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 类:
数据传送指令;
算术逻辑运算指令;
比较指令。
数据处理指令只能对寄存器的内容进行操作,
而不能对内存中的数据进行操作。
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 指令举例如下:
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
应用示例:
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
应用示例:
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 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
应用示例:
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}
应用示例:
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 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
ARM 具有三种乘法指令,分别为:
32×32 位乘法指令;
32× 32 位乘加指令;
Opcode 乘 法 指 令 操
作码 Rm 为被乘数寄存器
在 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}
带链接的分支指令—— 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 指令——协处理器指令
助记符 说明 操作 条件码位置
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} 存器的数据传送指令
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 表示回写
指令执行的条件码 协处理器编号
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 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 寄存器得到;
MRS 指令格式
MRS{cond} Rd,psr
指令对应编码
应用示例:
MRS R1,CPSR ; 将 CPSR 状态寄存器读取,保存到 R1
中
MRS R2,SPSR ; 将 SPSR 状态寄存器读取,保存到 R2
中
• ARM 杂项指令——状态寄存器写指令
在 ARM 处理器中,只有 MSR 指令可以对状态寄存器 CPSR 和 SPSR
进行写操作。与 MRS 配合使用,可以实现对 CPSR 或 SPSR 寄存器的读 -
修改 -写操作,可以切换处理器模式、或者允许 /禁止 IRQ/FIQ 中断等。
指令执行的条件码
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)
应用示例(源程序): 编译后的反汇编代码:
... ...
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 (查表):
应用示例(源程序):
...
ADRL R0,Delay
使用伪指令将程序标号
... Delay 的地址存入 R0
Delay
MOV R0,r14
...
• ARM 伪指令——大范围的地址读取
LDR 伪指令用于加载 32 位的立即数或一个地址值到指定寄存
器。
在汇编编译源程序时, LDR 伪指令被编译器替换成一
条合适的指令。若加载的常数未超出 MOV 或 MVN 的范围,则
使用 MOV 或 MVN 指令代替该 LDR 伪指令,否则汇编器将常
量放入文字池,并使用一条程序相对偏移的 LDR 指令从文字池
读出常量。 LDR 伪指令格式
LDR{cond} register,=expr
...
LDR R1,=InitStack
... 使用伪指令将程序标号
InitStack 的地址存入 R1
InitStack
MOV R0, LR
...
将超过 MOV 和 MVN
...
可操作范围的数
LDR R1,=0XFFF (即无效立即数),
装入寄存器 R1.
• ARM 伪指令——大范围的地址读取
应用示例(源程序):
编译后的反汇编代码:
...
LDR R1,=InitStack ...
使用伪指令将程序标号 地址 程序代码
InitStack 的地址存入 R1
• ARM 伪指令——大范围的地址读取
应用示例(源程序): 编译后的反汇编代码:
... ...
LDR R1,=InitStack 0x60 LDR R1,0xb4
... ...
InitStack 0x64 MOV R0, LR
MOV R0, LR ...
... 0xb4 DCD 0x64
注意:
1. 从指令位置到文字池的偏移量必须小于 4KB ;
2. 与 ARM 指 令 的 LDR 相 比 , 伪 指 令 的 LDR 的 参 数
有“ =” 号。
• ARM 伪指令——空操作伪指令
应用示例(延时子程序)
:
Delay
NOP ;空操作
NOP
NOP
SUBS R1,R1,#1 ;循环次数减一
BNE Delay ;如果循环没有结束,跳转 Delay 继
续
MOV PC,LR ;子程序返回
3 Thumb 指令集介绍
Thumb 指令
分支指令的跳转范围有更多限制;
数据处理指令的操作结果必须放入其中一个;
单寄存器访问指令,只能操作 R0 ~ R7 ;
助记符 说明 操作 影响标志
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 存储器访问指令
指令编码
L 用于区别加载( L 为
1 )还是存储( L 为
0)
应用示例:
LDMIA R0!,{R2-R7} ;加载 R0 指向的地址上的多字数据,
;保存到 R2 ~ R7 中, R0 的值更新。
STMIA R1!,{R2-R7} ;将 R2 ~ R7 的数据存储到 R1 指向的
;地址上, R1 值更新
Thumb 存储器访问指令
指令编码
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 寄存器中。
应用示例:
SUB SP,#-380 ;SP=SP-380
• 算术运算指令—— ADC
ADC 指令将 Rm 的值相加,再加上 CPSR 中的
C 条件标志位,结果保存到 Rd 寄存器。
ADC 指令格式:
ADC 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 移位操作:
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
应用示例:
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
应用示例:
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 表示程序标号。
应用示例: 反汇编代码:
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 ;子程序返回