Cortex-M4内核参考手册笔记-STM32 Cortex-M4 指令集
3.1 指令集概述
本处理器实现Thumb指令集版本。表21列出了支持的指令。
在表21中:
-
尖括号<>表示操作数的可选形式
-
花括号{}表示可选操作数
-
操作数列未穷举所有形式
-
Op2是灵活的第二操作数,可以是寄存器或常量
-
多数指令可使用可选的条件码后缀
更多指令和操作数信息,请参阅指令详细描述。









3.2 CMSIS 内联函数
ISO/IEC C代码无法直接访问某些Cortex-M4指令。本节描述由CMSIS提供的、可生成这些指令的内联函数,这些函数也可能由C编译器提供。若C编译器不支持相应的内联函数,则可能需要使用内联汇编来访问特定指令。
CMSIS提供了表22所列的内联函数,用于生成ANSI C无法直接访问的指令。
表22. 用于生成Cortex-M4指令的CMSIS内联函数

CMSIS还提供了一系列通过MRS和MSR指令访问特殊寄存器的函数(见表23)。
表23. 用于访问特殊寄存器的CMSIS内联函数

3.3 关于指令描述
3.3.1 操作数
指令操作数可以是Arm寄存器、常量或其他指令特定参数。指令对操作数执行操作后,通常将结果存储于目标寄存器中。若指令包含目标寄存器,该寄存器通常列在操作数之前。
部分指令的操作数具有灵活性,既可以是寄存器也可以是常量(参见"灵活的第二操作数")。
3.3.2 使用 PC 或 SP 时的限制
多数指令对程序计数器(PC)或堆栈指针(SP)能否作为操作数或目标寄存器存在限制。具体限制请参阅各指令描述。
通过BX、BLX、LDM、LDR或POP指令写入PC的地址必须满足bit[0]=1以确保正确执行,因为该位指示所需的指令集,而Cortex-M4处理器仅支持Thumb指令集。
3.3.3 灵活的第二操作数
许多通用数据处理指令具有灵活的第二操作数,在指令语法描述中显示为operand2。
operand2可以是:
-
常量
-
寄存器(可选带移位操作)
常量形式
操作数2的常量需以#constant形式指定,其中constant可为以下任意类型:
-
通过8位值左移任意位数生成的32位字常量
-
0x00XY00XY形式的常量
-
0xXY00XY00形式的常量
-
0xXYYXYXY形式的常量
(上述常量中X和Y代表十六进制数字)
少数指令支持更广范围的常量值,具体参见各指令独立描述。
当MOVS、MVNS、ANDS、ORRS、ORNS、EORS、BICS、TEQ或TST指令使用操作数2常量时:
-
若常量值>255且可由8位值移位产生,则进位标志(C)将更新为该常量bit[31]的值
-
其他类型常量不影响进位标志
指令替换机制
若指定非法常量,汇编器可能生成等效指令。例如:CMP Rd, #0xFFFFFFFE 可能被替换为等效的 CMN Rd, #0x2
寄存器带可选移位
操作数2寄存器格式为Rm (, shift),其中:
-
Rm:存储第二操作数的寄存器
-
Shift:可选移位操作(未指定时等效于LSL #0),支持以下类型:
ASR #n:算术右移n位(1≤n≤32)
LSL #n:逻辑左移n位(1≤n≤31)
LSR #n:逻辑右移n位(1≤n≤32)
ROR #n:循环右移n位(1≤n≤31)
RRX:带扩展的单次循环右移
——:若省略移位操作,则默认为LSL #0(不进行移位)
当省略移位操作或指定LSL #0时,指令将直接使用Rm寄存器中的值。
若指定移位操作:
-
系统会对Rm值进行移位处理,生成32位结果供指令使用
-
原Rm寄存器中的值保持不变
-
特定指令执行带移位的寄存器操作时,会更新进位标志位(C)
(移位操作对标志位的影响详见《移位操作》章节)
3.3.4 移位操作
寄存器移位操作将寄存器中的位向左或向右移动指定的位数(即移位长度)。寄存器移位可通过以下方式执行:
-
直接指令:ASR、LSR、LSL、ROR和RRX指令直接执行移位操作,结果写入目标寄存器。
-
操作数2的计算:在指定第二个操作数为带移位的寄存器时(参见第60页的灵活第二操作数),移位结果由指令使用。
允许的移位长度取决于移位类型和指令(详见各指令说明或灵活第二操作数)。若移位长度为0,则不进行移位。寄存器移位操作会更新进位标志,除非移位长度为0。以下小节描述了各种移位操作及其对进位标志的影响。在描述中,Rm是待移位的寄存器,*n*为移位长度。
ASR
算术右移*n*位将Rm寄存器的左起32-*n*位向右移动*n*位,存入结果的右起32-*n*位,同时将寄存器的原始bit[31]复制到结果的左起*n*位(参见第62页的图13:ASR #3)。
ASR #n操作可用于将Rm寄存器中的值除以2n2n,结果向负无穷方向取整。
当指令为ASRS,或在MOVS、MVNS、ANDS、ORRS、ORNS、EORS、BICS、TEO或TST指令中作为operand2使用ASR #n时,进位标志会更新为Rm寄存器移出的最后一位(bit[n-1])。
注意:
-
若*n*大于或等于32,则结果的所有位均设置为Rm的bit[31]值。
-
若*n*大于或等于32且更新了进位标志,则进位标志更新为Rm的bit[31]值。

LSR
逻辑右移 nn 位将 RmRm 寄存器的左起 32-nn 位向右移动 nn 位,存入结果的右起 32-nn 位,同时将结果的左起 nn 位设置为 0(见图 14)。
LSR #n 操作可用于将 RmRm 寄存器中的值除以 2n2n(前提是该值被视为无符号整数)。
当指令为 LSRS,或在 MOVS、MVNS、ANDS、ORRS、ORNS、EORS、BICS、TEQ 或 TST 指令中作为 operand2 使用 LSR #n 时,进位标志会更新为 RmRm 寄存器移出的最后一位(bit[n−1n−1])。
注意:
-
若 nn 大于或等于 32,则结果的所有位均清零为 0。
-
若 nn 大于或等于 33 且更新了进位标志,则进位标志更新为 0。

LSL
逻辑左移 nn 位将 RmRm 寄存器的右起 32-nn 位向左移动 nn 位,存入结果的左起 32-nn 位,同时将结果的右起 nn 位设置为 0(见图 15. LSL #3)。
LSL #n 操作可用于将 RmRm 寄存器中的值乘以 2n2n(无论该值被视为无符号整数还是二进制补码有符号整数)。溢出可能无警告。
当指令为 LSLS,或在 MOVS、MVNS、ANDS、ORRS、ORNS、EORS、BICS、TEQ 或 TST 指令中作为 operand2 使用非零 nn 的 LSL #n 时,进位标志会更新为 RmRm 寄存器移出的最后一位(bit[32−n32−n])。若使用 LSL #0,这些指令不会影响进位标志。
注意:
-
若 nn 大于或等于 32,则结果的所有位均清零为 0。
-
若 nn 大于或等于 33 且更新了进位标志,则进位标志更新为 0。

ROR
右循环移位 nn 位将 Rm 寄存器的左起 32-nn 位向右移动 nn 位,存入结果的右起 32-nn 位,同时将寄存器的右起 nn 位循环移至结果的左起 nn 位(见图 16)。
当指令为 RORS,或在 MOVS、MVNS、ANDS、ORRS、ORNS、EORS、BICS、TEQ 或 TST 指令中作为 operand2 使用 ROR #nn 时,进位标志会更新为 Rm 寄存器循环移出的最后一位(bit[nn-1])。
注意:
-
若 nn 为 32,则结果值与 Rm 中的值相同;若更新了进位标志,则进位标志更新为 Rm 的 bit[31]。
-
当移位长度 nn 大于 32 时,ROR 操作等效于移位长度为 nn-32 的 ROR。

RRX
带扩展的右循环移位将 Rm 寄存器的所有位向右移动 1 位,并将进位标志的值复制到结果的 bit[31](见图 17)。
当指令为 RRXS,或在 MOVS、MVNS、ANDS、ORRS、ORNS、EORS、BICS、TEG 或 TST 指令中作为 operand2 使用 RRX 时,进位标志会更新为 Rm 寄存器的 bit[0]。

3.3.5 地址对齐
对齐访问是指:对于字(word)、双字(dual word)或多字(multiple word)访问使用字对齐地址,或对于半字(halfword)访问使用半字对齐地址。字节(byte)访问始终是对齐的。
Cortex-M4处理器仅支持以下指令的非对齐访问:
-
LDR, LDRT
-
LDRH, LDRHT
-
LDRSH, LDRSHT
-
STR, STRT
-
STRH, STRHT
其他所有加载和存储指令若执行非对齐访问都会触发用法错误异常,因此这些指令的访问必须地址对齐。有关用法错误的更多信息,请参阅第44页的错误处理。
非对齐访问通常比对齐访问更慢。此外,某些内存区域可能不支持非对齐访问。因此,Arm建议程序员确保访问是对齐的。为避免意外产生非对齐访问,可使用配置和控制寄存器中的UNAUGN_TRP位来捕获所有非对齐访问,详见第231页的配置和控制寄存器(CCR)。
3.3.6 PC 相对寻址表达式
PC相对表达式(或称标签)是表示指令或字面数据地址的符号。在指令中,它表示为PC值加上或减去一个数字偏移量。汇编器根据标签和当前指令地址计算所需的偏移量。若偏移量过大,汇编器将报错。
-
对于B、BL、CBNZ和CBZ指令,PC值为当前指令地址加4字节。
-
对于其他使用标签的指令,PC值为当前指令地址加4字节,并将结果的bit[1]清零以确保字对齐。
-
某些汇编器可能支持其他PC相对表达式语法,例如标签加减数字,或[PC, #number]形式的表达式。
3.3.7 条件执行
大多数数据处理指令可选择根据操作结果更新应用程序状态寄存器(APSR)中的条件标志(见第21页的应用程序状态寄存器)。部分指令更新所有标志,部分仅更新子集。若标志未被更新,则保留原值。各指令影响的标志详见其描述。
可根据其他指令设置的条件标志来条件执行指令:
-
在更新标志的指令之后立即执行
-
在任意数量未更新标志的中间指令之后执行
可通过两种方式实现条件执行:使用条件分支指令,或在指令后添加条件码后缀(完整后缀列表参见第67页表24:条件码后缀)。条件码后缀使处理器能够基于标志位测试条件。若条件测试失败,该指令将:
-
不执行
-
不写入目标寄存器
-
不影响任何标志位
-
不触发任何异常
除条件分支指令外,所有条件指令必须位于IT指令块内(相关限制详见第145页IT指令说明)。部分汇编器在检测到IT块外的条件指令时可能自动插入IT指令。
CBZ和CBNZ指令可用于将寄存器值与零比较并根据结果跳转。
本节包含:
-
条件标志说明
-
条件码后缀(第67页)
条件标志说明
APSR包含以下条件标志位:
-
N(负标志):运算结果为负时置1,否则清零
-
Z(零标志):运算结果为零时置1,否则清零
-
C(进位标志):下列情况置1,否则清零
- V :当操作导致溢出时置1,否则清0。
有关APSR的更多信息,请参阅第19页的程序状态寄存器。
以下情况会产生进位(Carry):
-
加法结果大于或等于232232时。
-
减法结果为正数或零时。
-
在移动或逻辑指令中,内联桶形移位器操作产生的结果。
以下情况会发生溢出(Overflow):
-
如果两个负数相加结果为正数。
-
如果两个正数相加结果为负数。
-
如果从一个负数中减去一个正数得到正数结果。
-
如果从一个正数中减去一个负数得到负数结果。
比较操作(Compare)与减法(CMP)或加法(CMN)操作相同,只是结果会被丢弃。更多信息请参阅指令描述。
大多数指令仅在指定S后缀时更新状态标志。更多信息请参阅指令描述。
条件码后缀
可条件执行的指令拥有一个可选的条件码,在语法描述中表示为{cond}。条件执行需要前置的IT指令。只有当APSR中的条件码标志满足指定条件时,带有条件码的指令才会执行。_表24_列出了可用的条件码。
通过结合IT指令使用条件执行,可以减少代码中的分支指令数量。
_表24_还展示了条件码后缀与N、Z、C、V标志之间的关系。

表24. 条件码后缀
| 后缀 | 标志条件 | 含义 |
|---|---|---|
| EQ | Z=1Z=1 | 相等 |
| NE | Z=0Z=0 | 不相等 |
| CS或HS | C=1C=1 | 无符号大于或等于(≥) |
| CC或LO | C=0C=0 | 无符号小于(<) |
| MI | N=1N=1 | 负数 |
| PL | N=0N=0 | 正数或零 |
| VS | V=1V=1 | 溢出 |
| VC | V=0V=0 | 无溢出 |
| HI | C=1C=1且Z=0Z=0 | 无符号大于(>) |
| LS | C=0C=0或Z=1Z=1 | 无符号小于或等于(≤) |
| GE | N=VN=V | 有符号大于或等于(≥) |
| LT | N≠VN=V | 有符号小于(<) |
| GT | Z=0Z=0且N=VN=V | 有符号大于(>) |
| LE | Z=1Z=1且N≠VN=V | 有符号小于或等于(≤) |
| AL | 任意值 | 无条件执行(默认无后缀时使用) |
_具体示例1:绝对值_展示了如何使用条件指令计算一个数的绝对值。R0 = ABS(R1)。
具体示例1:绝对值
MOVS R0, R1 ; R0 = R1,并设置标志位 IT MI ; 为负数条件配置IT指令 RSBMI R0, R1, #0 ; 若为负数,R0 = -R1
_具体示例2:比较并更新值_展示了如何通过条件指令在R0和R2分别有符号大于R1和R3时更新R4的值。
具体示例2:比较并更新值
3.3.8 指令宽度选择
许多指令可以根据指定的操作数和目标寄存器生成16位或32位编码。对于其中部分指令,您可以通过使用指令宽度后缀强制指定指令大小。
-
.W后缀强制生成32位指令编码
-
.N后缀强制生成16位指令编码
若指定了指令宽度后缀但汇编器无法生成对应宽度的指令编码,将报错。
某些情况下必须显式指定.W后缀,例如当操作数是某条指令的标签或字面量数据时(如分支指令)。这是因为汇编器可能无法自动生成正确大小的编码。
使用指令宽度后缀时,需将其紧跟在指令助记符和条件码(如有)之后。
_具体示例3:指令宽度选择_展示了带宽度后缀的指令用法。
具体示例3:指令宽度选择
BCS.W label ; 即使短跳转也强制生成32位指令
ADDS.W R0, R0, R1 ; 即使可用16位指令也强制生成32位指令
3.4 存储器访问指令
表25展示了内存访问指令:

| 助记符 | 简要描述 | 参考位置 |
|---|---|---|
| ADR | 加载PC相对地址 | 第70页 ADR指令 |
| CLREX | 清除独占标记 | 第80页 CLREX指令 |
| LDM(mode) | 加载多寄存器 | 第76页 LDM和STM指令 |
| LDR(type) | 立即数偏移加载寄存器 | 第71页 LDR和STR(立即数偏移) |
| LDR(type) | 寄存器偏移加载寄存器 | 第73页 LDR和STR(寄存器偏移) |
| LDR(type)T | 非特权模式加载寄存器 | 第74页 LDR和STR(非特权访问) |
| LDR | PC相对地址加载寄存器 | 第75页 LDR(PC相对) |
| LDRD | 双寄存器加载 | 第71页 LDR和STR(立即数偏移) |
| LDREX(type) | 独占加载寄存器 | 第79页 LDREX和STREX指令 |
| POP | 从栈中弹出寄存器 | 第78页 PUSH和POP指令 |
| PUSH | 将寄存器压入栈 | 第78页 PUSH和POP指令 |
| STM(mode) | 存储多寄存器 | 第76页 LDM和STM指令 |
| STR(type) | 立即数偏移存储寄存器 | 第71页 LDR和STR(立即数偏移) |
| STR(type) | 寄存器偏移存储寄存器 | 第73页 LDR和STR(寄存器偏移) |
| STR(type)T | 非特权模式存储寄存器 | 第74页 LDR和STR(非特权访问) |
| STREX(type) | 独占存储寄存器 | 第79页 LDREX和STREX指令 |
3.4.1 ADR(地址加载)
加载PC相对地址
语法
ADR{cond} Rd, label
参数说明:
-
cond:可选条件码(参见第65页"条件执行") -
Rd:目标寄存器 -
label:PC相对表达式(参见第65页"PC相对表达式")
操作原理
ADR通过将立即数值与PC值相加来计算地址,并将结果写入目标寄存器。
由于采用PC相对寻址,ADR生成的代码具有位置无关性。
若使用ADR生成BX或BLX指令的目标地址,必须确保生成地址的bit[0]置1以保证正确执行。
label的取值范围必须为PC值±4095范围内。
注意:
如需获取最大偏移范围或生成非字对齐地址,可能需要使用.W后缀(参见第68页"指令宽度选择")。
限制条件
目标寄存器Rd不能是SP或PC。
状态标志
本指令不改变任何状态标志。
示例
ADR R1, TextMessage ; 将标签TextMessage的地址值写入R1
3.4.2 LDR 和 STR(立即数偏移)
支持立即数偏移、前变址立即数偏移和后变址立即数偏移的加载/存储操作
语法
op{type}{cond} Rt, [Rn {, #offset}] ; 立即数偏移 op{type}{cond} Rt, [Rn, #offset]! ; 前变址 op{type}{cond} Rt, [Rn], #offset ; 后变址 opD{cond} Rt, Rt2, [Rn {, #offset}] ; 双字立即数偏移 opD{cond} Rt, Rt2, [Rn, #offset]! ; 双字前变址 opD{cond} Rt, Rt2, [Rn], #offset ; 双字后变址
参数说明:
-
op:LDR(加载寄存器)或STR(存储寄存器)
-
type:
-
B:无符号字节(加载时零扩展至32位)
-
SB:有符号字节(仅LDR,符号扩展至32位)
-
H:无符号半字(加载时零扩展至32位)
-
SH:有符号半字(仅LDR,符号扩展至32位)
-
--:省略时表示字操作
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rt:待加载/存储的寄存器
-
Rn:基址寄存器
-
offset:相对于Rn的偏移量(省略时直接使用Rn的值作为地址)
-
Rt2:双字操作时的附加寄存器
操作原理
LDR指令从内存加载数据到1-2个寄存器,STR指令将1-2个寄存器的值存储到内存。
立即数偏移的加载/存储指令支持以下寻址模式:
-
偏移寻址
将偏移量与Rn中的地址相加/相减后作为访问地址,Rn值不变。
语法格式:[Rn, #offset] -
前变址寻址
先计算偏移量后的地址用于访问,再将结果写回Rn。
语法格式:[Rn, #offset]! -
后变址寻址
直接使用Rn值作为访问地址,操作后再将偏移量后的地址写回Rn。
语法格式:[Rn], #offset
可加载/存储的数据类型包括:字节、半字、字或双字。字节和半字可支持有符号或无符号格式(参见第65页地址对齐说明)。
*表26列出了立即数偏移、前变址和后变址形式的偏移量范围。

限制条件
-
加载指令(LDR):
-
仅当字加载时,
Rt可为SP或PC -
双字加载时,
Rt必须不同于R12 -
前变址/后变址模式下,
Rn必须不同于R1和R12
-
-
当PC作为字加载目标时:
-
加载值的bit[0]必须为1以确保正确执行
-
程序会跳转至bit[0]置0后的地址
-
若为条件指令,必须作为IT块的最后一条指令
-
-
存储指令(STR):
-
仅当字存储时,
Rt可为SP -
Rt不可为PC -
Rn不可为PC -
前变址/后变址模式下,
Rn必须不同于R1和R12
-
状态标志
这些指令不会改变任何状态标志。
示例
LDR R8, [R10] ; 将R10指向的地址内容加载到R8
LDRNE R2, [R5, #960] ; (条件执行)将R5+960地址的字数据加载到R2
; 并将R5值增加960
STR R2, [R9, #const-struct]; const-struct为取值0-4095的常数表达式
; 将R2存储到R9+const-struct地址
STRH R3, [R4], #4 ; 将R3作为半字存入R4指向地址,随后R4+=4
LDRD R8, R9, [R3, #0x20]! ; 从R3+0x20加载双字到R8/R9,并更新R3值
STRD R0, R1, [R8], #-16 ; 将R0/R1双字存入R8/R8+4地址,随后R8-=16
3.4.3 LDR 和 STR(寄存器偏移)
基于寄存器的加载与存储
语法
其中:
-
op:可以是LDR(加载寄存器)或STR(存储寄存器)。
-
type:可选以下类型之一:
-
B:无符号字节,加载时零扩展至32位。
-
SB:有符号字节,加载时符号扩展至32位(仅LDR支持)。
-
H:无符号半字,加载时零扩展至32位。
-
SH:有符号半字,加载时符号扩展至32位(仅LDR支持)。
-
--:省略,表示字(word)。
-
-
cond:可选条件码,参见第65页的“条件执行”。
-
Rt:待加载或存储的寄存器。
-
Rn:基址寄存器,内存地址基于此寄存器。
-
Rm:包含偏移值的寄存器。
-
LSL #n:可选移位操作,n取值范围为0到3。
操作
LDR指令从内存加载值到寄存器,STR指令将寄存器值存储到内存。内存地址为基址寄存器Rn加上偏移值(由Rm指定,并可选择左移最多3位)。加载或存储的值可以是字节、半字或字。对于加载指令,字节和半字可支持有符号或无符号扩展(参见第65页的“地址对齐”)。
限制
-
Rn不能为PC。
-
Rm不能是SP或PC。
-
Rt仅在字加载和字存储时可为SP。
-
Rt仅在字加载时可为PC。
当Rt为PC且执行字加载时:
-
加载值的bit[0]必须为1以确保正确执行,程序会跳转到该半字对齐的地址。
-
若指令为条件指令,则必须是IT块中的最后一条指令。
条件标志位
这些指令不会改变标志位。
示例
3.4.4 LDR 和 STR(非特权模式)
支持非特权模式的加载与存储
语法
其中:
-
op:可以是LDR(加载寄存器)或STR(存储寄存器)。
-
type:可选以下类型之一:
-
B:无符号字节,加载时零扩展至32位。
-
SB:有符号字节,加载时符号扩展至32位(仅LDR支持)。
-
H:无符号半字,加载时零扩展至32位。
-
SH:有符号半字,加载时符号扩展至32位(仅LDR支持)。
-
--:省略,表示字(word)。
-
-
cond:可选条件码,参见第65页的“条件执行”。
-
Rt:待加载或存储的寄存器。
-
Rn:基址寄存器,内存地址基于此寄存器。
-
offset:相对于Rn的偏移量,取值范围为0到255。若省略,则地址为Rn中的值。
操作
这些加载与存储指令的功能与“立即数偏移的LDR和STR指令”(参见第71页)相同,区别在于:即使运行在特权模式下,这些指令也仅以非特权权限访问内存。
在非特权模式下,这些指令的行为与普通立即数偏移的内存访问指令完全一致。
限制
-
Rn不能为PC。
-
Rt不能是SP或PC。
条件标志位
这些指令不会改变标志位。
示例
3.4.5 LDR(PC 相对寻址)
从内存加载寄存器(基于PC的地址)
语法
其中:
-
type:可选以下类型之一:
-
B:无符号字节,零扩展至32位。
-
SB:有符号字节,符号扩展至32位。
-
H:无符号半字,零扩展至32位(注:原文误写为“sign extends”,应为“zero extends”)。
-
SH:有符号半字,符号扩展至32位。
-
--:省略,表示字(word)。
-
-
cond:可选条件码,参见第65页的“条件执行”。
-
Rt:目标寄存器(加载值存放位置)。
-
Rt2:第二目标寄存器(仅LDRD指令使用)。
-
label:PC相对地址表达式(参见第65页的“PC相对表达式”)。
操作
LDR指令从PC相对寻址的内存地址加载值到寄存器。内存地址由标签或相对于PC的偏移量指定。可加载的值为字节、半字或字,且支持有符号/无符号扩展(参见第65页的“地址对齐”)。
标签范围限制
-
单字/半字/字节加载:标签与PC的偏移范围为 -4095至4095。
-
双字加载(LDRD):标签与PC的偏移范围为 -1020至1020。
若超出默认范围,需使用.W后缀扩展偏移量(参见第68页的“指令宽度选择”)。

限制
-
Rt2不能为SP或PC。
-
Rt必须与Rt2不同。
-
Rt仅在字加载时可为SP或PC。
-
当Rt为PC且执行字加载时:
-
加载值的bit[0]必须为1以确保正确执行,程序会跳转到该半字对齐的地址。
-
若指令为条件指令,则必须是IT块中的最后一条指令。
-
条件标志位
这些指令不会改变标志位。
示例
LDR R0, LookUpTable ; 从标签为LookUpTable的地址加载一个字数据到R0 LDRSB R7, localdata ; 从标签为localdata的地址加载一个字节值,符号扩展为字后存入R7
3.4.6 LDM 和 STM(多寄存器加载/存储)
多寄存器加载与存储
语法
其中:
-
op:可以是LDM(加载多寄存器)或STM(存储多寄存器)。
-
addr_mode:寻址模式,可选以下之一:
-
IA:每次访问后递增地址(默认模式)。
-
DB:每次访问前递减地址。
-
-
cond:可选条件码,参见第65页的“条件执行”。
-
Rn:基址寄存器,内存地址基于此寄存器。
-
!:可选回写后缀。若存在,最终访问的地址将写回Rn。
-
reglist:待加载或存储的寄存器列表,用大括号包围,可包含寄存器范围(多个寄存器或范围需用逗号分隔,参见第77页示例)。
指令别名
-
LDM、LDMFD 是 LDMIA 的同义词。LDMFD表示用于从满递减栈弹出数据。
-
LDMEA 是 LDMDB 的同义词,表示用于从空递增栈弹出数据。
-
STM、STMEA 是 STMIA 的同义词。STMEA表示用于向空递增栈压入数据。
-
STMFD 是 STMDB 的同义词,表示用于向满递减栈压入数据。
操作
-
LDM指令:从基于Rn的内存地址加载字数据到
reglist中的寄存器。 -
STM指令:将
reglist中寄存器的字数据存储到基于Rn的内存地址。
对于LDM、LDMIA、LDMFD、STM、STMIA和STMEA指令,访问的内存地址以4字节为间隔,范围从RnRn到Rn+4∗(n−1)Rn+4∗(n−1),其中nn是寄存器列表_reglist_中的寄存器数量。访问按寄存器编号的升序进行,编号最小的寄存器使用最低的内存地址,编号最大的寄存器使用最高的内存地址。如果指定了写回后缀,则将Rn+4∗(n−1)Rn+4∗(n−1)的值写回RnRn。
对于LDMDB、LDMEA、STMDB和STMFD指令,访问的内存地址以4字节为间隔,范围从RnRn到Rn−4∗(n−1)Rn−4∗(n−1),其中nn是寄存器列表_reglist_中的寄存器数量。访问按寄存器编号的降序进行,编号最大的寄存器使用最高的内存地址,编号最小的寄存器使用最低的内存地址。如果指定了写回后缀,则将Rn−4∗(n)Rn−4∗(n)的值写回RnRn。
PUSH和POP指令可以用这种形式表示(详见_PUSH和POP_部分)。
限制条件
在这些指令中:
-
_Rn不能是PC。
-
_reglist不能包含SP。
-
在任何STM指令中,_reglist不能包含PC。
-
在任何LDM指令中,如果_reglist包含LR,则不能包含PC。
-
如果指定了写回后缀,_reglist不能包含_Rn_。
当PC出现在LDM指令的_reglist_中时:
-
*加载到PC的值的bit[0]必须为1以确保正确执行,程序会跳转到这个半字对齐的地址。
-
*如果指令是条件执行的,它必须是IT块中的最后一条指令。
条件标志
这些指令不会改变标志位。
示例

3.4.7 PUSH 和 POP(压栈/出栈)
将寄存器压入(PUSH)或弹出(POP)满递减栈。PUSH和POP分别是STMDB和LDM(或LDMIA)的别名,其内存访问基于SP寄存器,并将最终访问地址写回SP。在此类场景中,推荐使用PUSH和POP助记符。
语法
参数说明:
-
cond:可选条件码(参见第65页“条件执行”)。 -
reglist:非空的寄存器列表(或寄存器范围),用大括号包裹。多个寄存器或范围间需用逗号分隔(示例见第77页)。
操作行为
-
PUSH 按寄存器编号降序将寄存器存入栈,编号最大的寄存器使用最高内存地址,编号最小的寄存器使用最低内存地址。
-
POP 按寄存器编号升序从栈加载寄存器,编号最小的寄存器使用最低内存地址,编号最大的寄存器使用最高内存地址。
-
PUSH 以
SP-4为最高内存地址,POP 以SP值为最低内存地址,实现满递减栈。执行完成后:-
PUSH更新SP指向最后一次存储的最低地址。
-
POP更新SP指向已加载最高地址的上一个位置。
-
-
若POP指令的
reglist包含PC,则指令完成后会跳转到该地址。此时:-
写入PC的值的bit[0]用于更新APSR的T位,且必须为1以确保正确操作。
-
更多细节参见第76页“LDM与STM”。
-
限制条件
-
reglist不得包含SP。 -
PUSH指令的
reglist不得包含PC。 -
POP指令的
reglist若包含LR,则不得同时包含PC。若POP的reglist包含PC:-
加载到PC的值的bit[0]必须为1,程序会跳转到此半字对齐地址。
-
若为条件指令,则必须是IT块的最后一条指令。
-
条件标志
这些指令不会改变标志位。
示例
PUSH {R0,R4-R7} ; 将R0、R4、R5、R6、R7压入栈
PUSH {R2,LR} ; 将R2和链接寄存器(LR)压入栈
POP {R0,R6,PC} ; 从栈弹出R0、R6和PC,并跳转到新PC地址
3.4.8 LDREX 和 STREX(独占加载/存储)
独占式加载与存储寄存器。
语法
参数说明
-
cond:可选条件码(参见第65页“条件执行”)。
-
Rd:用于返回状态的目标寄存器。
-
Rt:待加载或存储的寄存器。
-
Rn:基址寄存器,用于计算内存地址。
-
offset:可选偏移量,作用于 Rn 的值。若省略,则地址直接使用 Rn 的值。
操作行为
-
LDREX、LDREXB 和 LDREXH 分别从内存地址加载一个字(word)、字节(byte)和半字(halfword)。
-
STREX、STREXB 和 STREXH 尝试向内存地址分别存储一个字、字节和半字。
-
独占存储指令使用的地址必须与最近一次独占加载指令的地址相同。
-
存储的数据大小必须与之前加载的数据大小一致。
-
软件必须配对使用独占加载和独占存储指令以实现同步操作(详见第34页“同步原语”)。
-
-
若独占存储指令执行成功(完成存储),则向目标寄存器 Rd 写入 0;若失败,则写入 1。
-
当 Rd 为 0 时,可确保在独占加载和独占存储之间没有其他进程访问该内存位置。
-
-
出于性能考虑,应尽量减少独占加载与独占存储指令之间的指令数量。
注意:若独占存储指令的地址与之前的独占加载指令地址不同,执行结果不可预测。
限制条件
使用这些指令时需遵守以下规则:
禁止使用PC寄存器
禁止将SP寄存器用于Rd和Rt
STREX指令中,Rd必须与Rt、Rn均不同
偏移量offset的值必须是4的倍数,且范围在0-1020之间
条件标志位
这些指令不会改变处理器标志位。
示例代码
MOV R1, #0x1 ; 初始化'lock taken'值 try: LDREX R0, [LockAddr] ; 加载锁状态值 CMP R0, #0 ; 检查锁是否空闲 ITT EQ ; 为STREXEQ和CMPEQ设置条件执行块 STREXEQ R0, R1, [LockAddr] ; 尝试获取锁 CMPEQ R0, #0 ; 检查是否获取成功 BNE try ; 失败则重试 ; 成功获得锁
3.4.9 CLREX(清除独占状态)
CLREX指令
清除独占状态。
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行")
操作行为
CLREX指令会使后续的STREX/STREXB/STREXH指令:
-
向目标寄存器写入1
-
强制存储操作失败
典型应用场景:
在异常处理程序中,当同步操作(位于独占加载和独占存储指令之间)被异常中断时,通过CLREX强制使存储操作失败。
更多细节请参考第34页"同步原语"。
条件标志位
本指令不会改变处理器标志位。
示例
CLREX
3.5 通用数据处理指令


表28列出了所有数据处理指令的概要信息。
| 表28. 数据处理指令总览 | ||
|---|---|---|
| 助记符 | 功能简述 | 详细说明页码 |
| ADC | 带进位加法 | 参见第83页「ADD、ADC、SUB、SBC和RSB」 |
| ADD | 加法运算 | 参见第83页「ADD、ADC、SUB、SBC和RSB」 |
| ADDW | 加法运算(宽立即数) | 参见第83页「ADD、ADC、SUB、SBC和RSB」 |
| AND | 逻辑与 | 参见第85页「AND、ORR、EOR、BIC和ORN」 |
| ASR | 算术右移 | 参见第86页「ASR、LSL、LSR、ROR和RRX」 |
| BIC | 位清除 | 参见第85页「AND、ORR、EOR、BIC和ORN」 |
| CLZ | 前导零计数 | 参见第87页「CLZ」 |
| CMN | 负向比较 | 参见第88页「CMP和CMN」 |
| CMP | 比较运算 | 参见第88页「CMP和CMN」 |
| EOR | 异或运算 | 参见第85页「AND、ORR、EOR、BIC和ORN」 |
| LSL | 逻辑左移 | 参见第86页「ASR、LSL、LSR、ROR和RRX」 |
| LSR | 逻辑右移 | 参见第86页「ASR、LSL、LSR、ROR和RRX」 |
| MOV | 数据搬移 | 参见第89页「MOV和MVN」 |
| MOVT | 高16位数据搬移 | 参见第91页「MOVT」 |
| MOVW | 16位立即数搬移 | 参见第89页「MOV和MVN」 |
| MVN | 数据取反搬移 | 参见第89页「MOV和MVN」 |
| ORN | 逻辑或非 | 参见第85页「AND、ORR、EOR、BIC和ORN」 |
| ORR | 逻辑或 | 参见第85页「AND、ORR、EOR、BIC和ORN」 |
| RBIT | 位序反转 | 参见第92页「REV、REV16、REVSH和RBIT」 |
| REV | 字内字节反序 | 参见第92页「REV、REV16、REVSH和RBIT」 |
| REV16 | 半字内字节反序 | 参见第92页「REV、REV16、REVSH和RBIT」 |
| REVSH | 低半字反序并符号扩展 | 参见第92页「REV、REV16、REVSH和RBIT」 |
| ROR | 循环右移 | 参见第86页「ASR、LSL、LSR、ROR和RRX」 |
| RRX | 带扩展循环右移 | 参见第86页「ASR、LSL、LSR、ROR和RRX」 |
| RSB | 反向减法 | 参见第83页「ADD、ADC、SUB、SBC和RSB」 |
| SADD16 | 有符号16位加法 | 参见第93页「SADD16和SADDB」 |
| SADDB | 有符号8位加法 | 参见第93页「SADD16和SADDB」 |
| SASX | 有符号加减交换运算 | 参见第98页「SASX和SSAX」 |
| SSAX | 有符号减加交换运算 | 参见第98页「SASX和SSAX」 |
| SBC | 带借位减法 | 参见第83页「ADD、ADC、SUB、SBC和RSB」 |
| SHADD16 | 有符号16位半加 | 参见第94页「SHADD16和SHADDB」 |
| SHADDB | 有符号8位半加 | 参见第94页「SHADD16和SHADDB」 |
表28. 数据处理指令(续)
| 助记符 | 功能描述 | 详细说明页码 |
|---|---|---|
| SHASX | 有符号半加半减交换运算 | 第95页「SHASX与SHSAX」 |
| SHSAX | 有符号半减半加交换运算 | 第95页「SHASX与SHSAX」 |
| SHSUB16 | 有符号16位半减 | 第96页「SHSUB16与SHSUB8」 |
| SHSUB8 | 有符号8位半减 | 第96页「SHSUB16与SHSUB8」 |
| SSUB16 | 有符号16位减法 | 第97页「SSUB16与SSUB8」 |
| SSUB8 | 有符号8位减法 | 第97页「SSUB16与SSUB8」 |
| SUB | 减法运算 | 第83页「ADD/ADC/SUB/SBC/RSB」 |
| SUBW | 减法运算(宽立即数) | 第83页「ADD/ADC/SUB/SBC/RSB」 |
| TEQ | 等价测试 | 第93页「SADD16与SADDB」 |
| TST | 位测试 | 第93页「SADD16与SADDB」 |
| UADD16 | 无符号16位加法 | 第100页「UADD16与UADDB」 |
| UADDB | 无符号8位加法 | 第100页「UADD16与UADDB」 |
| UASX | 无符号加减交换运算 | 第101页「UASX与USAX」 |
| USAX | 无符号减加交换运算 | 第101页「UASX与USAX」 |
| UHADD16 | 无符号16位半加 | 第102页「UHADD16与UHADDB」 |
| UHADDB | 无符号8位半加 | 第102页「UHADD16与UHADDB」 |
| UHASX | 无符号半加半减交换运算 | 第103页「UHASX与UHSAX」 |
| UHSAX | 无符号半减半加交换运算 | 第103页「UHASX与UHSAX」 |
| UHSUB16 | 无符号16位半减 | 第104页「UHSUB16与UHSUB8」 |
| UHSUB8 | 无符号8位半减 | 第104页「UHSUB16与UHSUB8」 |
| USAD8 | 无符号绝对差值和 | 第106页「USAD8」 |
| USADA8 | 无符号绝对差值累加 | 第107页「USADA8」 |
| USUB16 | 无符号16位减法 | 第108页「USUB16与USUB8」 |
| USUB8 | 无符号8位减法 | 第108页「USUB16与USUB8」 |
3.5.1 ADD(加法)、ADC(带进位加法)、SUB(减法)、SBC(带借位减法)、RSB(反向减法)
加法、带进位加法、减法、带借位减法及反向减法
语法
参数说明:
-
op:指令类型,可选以下之一:
-
ADD:加法
-
ADC:带进位加法
-
SUB:减法
-
SBC:带借位减法
-
RSB:反向减法
-
-
S:可选后缀。若指定,则根据运算结果更新条件标志位(参见第65页"条件执行")
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器。若省略,则目标寄存器为Rn
-
Rn:存放第一操作数的寄存器
-
Operand2:灵活的第二操作数(选项详见第60页"灵活第二操作数")
-
imm12:0-4095范围内的立即数
操作行为
-
ADD:将Operand2或imm12的值与Rn值相加
-
ADC:将Rn值、Operand2值及进位标志位三者相加
-
SUB:从Rn值中减去Operand2或imm12的值
-
SBC:从Rn值中减去Operand2值,若进位标志为0,结果再减1
-
RSB:用Operand2值减去Rn值(利用Operand2的灵活选项实现特殊运算)
应用场景
-
使用ADC和SBC实现多字长算术运算(参见第84页"多字长运算示例"及第70页"ADR指令")
-
ADDW等效于使用imm12操作数的ADD语法,SUBW等效于使用imm12操作数的SUB语法
限制条件
使用这些指令时需遵守以下规则:
-
Operand2 不得为SP或PC
-
Rd 仅在ADD和SUB指令中可为SP,且需满足:
-
Rn必须同为SP
-
Operand2的移位操作仅限LSL,且最大移位数3位
-
-
Rn 仅在ADD和SUB指令中可为SP
-
Rd 仅在特定ADD指令中可为PC:
ADD{cond} PC, PC, Rm-
不可使用S后缀
-
Rm不得为PC或SP
-
若为条件指令,必须是IT块的最后一条指令
-
-
除上述特殊ADD指令外,Rn 仅在ADD/SUB中可为PC,且需满足:
-
不可使用S后缀
-
第二操作数必须为0-4095的立即数
-
注意:
使用PC进行加减法时,PC的[1:0]位会强制对齐到b00(字对齐地址)
生成指令地址时,需根据PC值调整立即数。ARM推荐使用ADR指令替代ADD/SUB(汇编器会自动计算正确立即数)
当指令为 ADD{cond} PC, PC, Rm 且Rd=PC时:
-
写入PC的值的bit[0]被忽略
-
强制bit[0]=0后跳转到目标地址
条件标志位
若指定S后缀,指令将根据运算结果更新N/Z/C/V标志位。
示例
ADD R2, R1, R3 ; R2 = R1 + R3 SUBS R8, R6, #240 ; R8 = R6 - 240,并更新标志位 RSB R4, R4, #1280 ; R4 = 1280 - R4 ADCHI R11, R0, R3 ; 仅当C=1且Z=0时执行:R11 = R0 + R3 + C ; 64位加法示例:将R2:R3加到R0:R1,结果存至R4:R5

ADDS R4, R0, R2 ; 低32位相加(更新标志位)
ADC R5, R1, R3 ; 高32位带进位相加
多寄存器值运算
多字长数值可不使用连续寄存器。示例5:96位减法演示了从R6/R2/R8存储的96位整数中减去R9/R1/R11存储的96位整数,结果存回R6/R9/R2。
示例5:96位减法
SUB R6, R6, R9 ; 低32位减法 SBCS R9, R2, R1 ; 中32位带借位减法(更新标志位) SBC R2, R8, R11 ; 高32位带借位减法
3.5.2 AND(与)、ORR(或)、EOR(异或)、BIC(位清除)、ORN(或非)
逻辑与、或、异或、位清除及或非运算
语法
参数说明:
-
op:指令类型,可选以下之一:
-
AND:逻辑与运算
-
ORR:逻辑或运算(位设置)
-
EOR:逻辑异或运算
-
BIC:逻辑与非运算(位清除)
-
ORN:逻辑或非运算
-
-
S:可选后缀。若指定,则根据运算结果更新条件标志位(参见第65页"条件执行")
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器(若省略,则目标寄存器为Rn)
-
Rn:存放第一操作数的寄存器
-
Operand2:灵活第二操作数(选项详见第60页"灵活第二操作数")
操作行为
-
AND/EOR/ORR:对Rn和Operand2的值执行按位与/异或/或运算
-
BIC:将Rn的值与Operand2值的反码进行按位与运算
-
ORN:将Rn的值与Operand2值的反码进行按位或运算
限制条件
禁止使用SP(栈指针)或PC(程序计数器)寄存器。
条件标志位
若指定S后缀,这些指令将:
-
根据运算结果更新N(负标志)和Z(零标志)
-
在计算Operand2时可能更新C(进位标志),详见第60页"灵活第二操作数"
-
不影响V(溢出标志)
示例
AND R9, R2, #0xFF00 ; R9 = R2 & 0xFF00(按位与)
ORREQ R2, R0, R5 ; 当Z=1时执行:R2 = R0 | R5(按位或)
ANDS R9, R8, #0x19 ; R9 = R8 & 0x19,并更新标志位
BIC R7, R11, #0x18181818 ; R7 = R11 & ~0x18181818(位清除)
ORN R7, R11, R14, ROR #4 ; R7 = R11 | ~(R14循环右移4位)
ORNS R7, R11, R14, ASR #32; R7 = R11 | (R14算术右移32位),并更新标志位
3.5.3 ASR(算术右移)、LSL(逻辑左移)、LSR(逻辑右移)、ROR(循环右移)、RRX(带扩展循环右移)
算术右移、逻辑左移、逻辑右移、循环右移,以及带扩展的循环右移。
语法
其中:
-
op 是以下指令之一:
-
ASR:算术右移
-
LSL:逻辑左移
-
LSR:逻辑右移
-
ROR:循环右移
-
-
S 为可选后缀。若指定 S,则根据操作结果更新条件码标志位,详见第65页的“条件执行”。
-
Rd 是目标寄存器。
-
Rm 是存放待移位值的寄存器。
-
Rs 是存放移位长度的寄存器,仅使用最低有效字节,范围为0至255。
-
n 是移位长度,范围取决于具体指令:
-
ASR:1至32
-
LSL:0至31
-
LSR:1至32
-
ROR:1至31
-
注意:
MOVS Rd, Rm是LSLS Rd, Rm, #0的首选语法。操作
ASR、LSL、LSR 和 ROR 将寄存器 Rm 中的位向左或向右移动指定的位数,移动位数由常量 n 或寄存器 Rs 指定。
RRX 将寄存器 Rm 中的位向右移动 1 位。
在所有这些指令中,结果会被写入 Rd,但 Rm 寄存器中的值保持不变。关于不同指令生成的具体结果,请参阅第62页的“移位操作”。
限制
不要使用 SP(栈指针)或 PC(程序计数器)。
条件标志
如果指定了 S 后缀:
这些指令会根据结果更新 N(负标志)和 Z(零标志)。
C(进位标志)会被更新为最后移出的位,除非移位长度为 0(详见第62页的“移位操作”)。
示例
ASR R7, R8, #9 ; 算术右移 9 位 LSLS R1, R2, #3 ; 逻辑左移 3 位并更新标志位 LSR R4, R5, #6 ; 逻辑右移 6 位 ROR R4, R5, R6 ; 按 R6 最低字节的值循环右移 RRX R4, R5 ; 带扩展的循环右移
3.5.4 CLZ(前导零计数)
前导零计数。
语法
其中:
-
cond 是可选的条件码(详见第65页的“条件执行”)。
-
Rd 是目标寄存器。
-
Rm 是操作数寄存器。
操作
CLZ 指令计算 Rm 中值的前导零数量,并将结果存入 Rd。如果源寄存器中没有置位(即值为 0),则结果为 32;如果最高位(bit[31])已置位,则结果为 0。
限制
-
不要使用 SP(栈指针)或 PC(程序计数器)。
条件标志
此指令不会改变条件标志。

3.5.5 CMP(比较)、CMN(负数比较)
比较与负向比较
语法
其中:
-
cond 为可选条件码(详见第65页"条件执行")。
-
Rn 为存放第一操作数的寄存器。
-
Operand2 为灵活的第二操作数(具体选项详见第60页"灵活第二操作数")。
操作
这些指令将寄存器中的值与Operand2进行比较,并根据结果更新条件标志位,但不会将结果写入寄存器。
-
CMP指令 从Rn值中减去Operand2的值,其功能等同于SUBS指令,但会丢弃运算结果。
-
CMN指令 将Rn值与Operand2相加,其功能等同于ADDS指令,但会丢弃运算结果。
限制
使用这些指令时需注意:
-
禁止使用PC(程序计数器)
-
Operand2不得为SP(栈指针)
条件标志
这些指令会根据运算结果更新N(负标志)、Z(零标志)、C(进位标志)和V(溢出标志)。
示例
CMP R2, R9 ; 比较R2与R9
CMN R0, #6400 ; R0值与立即数6400相加比较
CMPGT SP, R7, LSL #2 ; 若大于条件成立,比较SP与R7左移2位后的值
3.5.6 MOV(移动)、MVN(取反移动)
数据传送与数据非传送
语法
其中:
-
S 为可选后缀。若指定S,则根据操作结果更新条件码标志位(详见第65页"条件执行")
-
cond 为可选条件码(详见第66页"条件执行")
-
Rd 为目标寄存器
-
Operand2 为灵活的第二操作数(具体选项详见第60页"灵活第二操作数")
-
imm16 为0-65535范围内的任意值
操作
MOV指令 将Operand2的值复制到Rd寄存器:
-
当MOV指令的Operand2为带有移位操作(非LSL#0)的寄存器时,推荐使用对应的移位指令语法:
-
ASR{S}{cond} Rd, Rm, #n是MOV{S}{cond} Rd, Rm, ASR #n的推荐写法 -
LSL{S}{cond} Rd, Rm, #n是MOV{S}{cond} Rd, Rm, LSL #n(当n≠0时)的推荐写法 -
同理适用于LSR、ROR和RRX操作
-
-
MOV指令还支持以下移位指令的等价写法:
-
MOV{S}{cond} Rd, Rm, ASR Rs等价于ASR{S}{cond} Rd, Rm, Rs -
同理适用于LSL、LSR和ROR操作
-
(详见第86页"ASR、LSL、LSR、ROR和RRX")
MVN指令 对Operand2的值执行按位逻辑非(NOT)操作,并将结果存入Rd。
注意:
MOVW指令功能与MOV相同,但仅支持imm16操作数。
限制条件
仅在MOV指令中可使用SP(栈指针)和PC(程序计数器),但需遵守以下限制:
-
第二操作数必须为不带移位操作的寄存器
-
禁止使用S后缀
当MOV指令的目标寄存器为PC时:
-
写入PC的值的bit[0]将被忽略
-
程序会跳转到将该值bit[0]强制置0后生成的地址
注意:
虽然可用MOV实现分支跳转,但Arm强烈建议使用BX或BLX指令以保持与Arm指令集的软件兼容性。
条件标志
若指定S后缀,这些指令会:
-
根据结果更新N(负标志)和Z(零标志)
-
在计算Operand2时可能更新C(进位标志)(详见第60页"灵活第二操作数")
-
不影响V(溢出标志)
示例

MOVS R11, #0x000B ; 将0x000B写入R11,并更新标志位 MOV R1, #0xFA05 ; 将0xFA05写入R1,不更新标志位 MOVS R10, R12 ; 将R12值写入R10,并更新标志位 MOV R3, #23 ; 将立即数23写入R3 MOV R8, SP ; 将栈指针值写入R8 MVNS R2, #0xF ; 将0xF按位取反(0xFFFFFFF0)写入R2,并更新标志位
3.5.7 MOVT(移动高16位)
高半字数据传送
语法
其中:
-
cond 为可选条件码(详见第65页"条件执行")
-
Rd 为目标寄存器
-
imm16 为16位立即数
操作
MOVT将16位立即数imm16写入目标寄存器的高半字(Rd[31:16]),该操作不会影响寄存器的低半字(Rd[15:0])。
MOV与MOVT指令配合使用,可生成任意32位常数。
限制
-
目标寄存器Rd不能为SP(栈指针)或PC(程序计数器)
条件标志
本指令不会改变任何条件标志位。
示例
MOVT R3, #0xF123 ; 将0xF123写入R3的高半字 ; R3的低半字和APSR状态寄存器保持不变
3.5.8 REV(字节反转)、REV16(半字反转)、REVSH(有符号半字反转)、RBIT(位反转)
字节序反转与位序反转
语法
其中:
-
op 为以下指令之一:
-
REV:反转字(32位)内的字节顺序
-
REV16:分别反转每个半字(16位)内的字节顺序
-
REVSH:反转低半字的字节顺序并符号扩展至32位
-
RBIT:反转32位字中的位顺序
-
-
cond 为可选条件码(详见第65页"条件执行")
-
Rd 为目标寄存器
-
Rn 为存放操作数的寄存器
操作
这些指令用于改变数据的字节序:
-
REV:实现32位数据的字节序转换
-
大端序 ↔ 小端序
-
-
REV16:实现16位半字的字节序转换
-
大端序 ↔ 小端序(每个半字独立处理)
-
-
REVSH:实现16位有符号数据的转换
-
大端序有符号数据 → 32位小端序有符号数据
-
小端序有符号数据 → 32位大端序有符号数据
-
限制
-
禁止使用SP(栈指针)或PC(程序计数器)
条件标志
这些指令不会改变任何条件标志位。
示例
REV R3, R7 ; 反转R7值的字节顺序后写入R3 REV16 R0, R0 ; 反转R0中每个半字的字节顺序 REVSH R0, R5 ; 反转有符号半字并符号扩展 REVHS R3, R7 ; 满足HS(无符号大于等于)条件时执行字节反转 RBIT R7, R8 ; 反转R8值的位顺序后写入R7
3.5.9 SADD16和SADD8(有符号16位/8位加法)
有符号16位加法与有符号8位加法
语法
其中:
-
op 为以下指令之一:
-
SADD16:执行两组16位有符号整数加法
-
SADDB:执行四组8位有符号整数加法
-
-
cond 为可选条件码(详见第65页"条件执行")
-
Rd 为目标寄存器
-
Rn 为第一操作数寄存器
-
Rm 为第二操作数寄存器
操作
这些指令实现并行半字/字节加法运算:
SADD16指令:
-
将第一操作数的每个半字与第二操作数对应半字相加
-
结果写入目标寄存器的对应半字
SADDB指令:
-
将第一操作数的每个字节与第二操作数对应字节相加
-
结果写入目标寄存器的对应字节
限制
-
禁止使用SP(栈指针)和PC(程序计数器)
条件标志
这些指令不会改变任何条件标志位。
示例
SADD16 R1, R0 ; 将R0的每个半字与R1对应半字相加,结果写入R1对应半字 SADDB R4, R0, R5 ; 将R0的每个字节与R5对应字节相加,结果写入R4对应字节
3.5.10 SHADD16和SHADD8(有符号半字/字节加法并右移)
有符号半减加法(16位/8位)
语法
参数说明:
-
op 支持以下指令:
-
SHADD16:16位有符号半减加法
-
SHADDB:8位有符号半减加法
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
功能描述
实现16位/8位数据相加后右移一位(结果减半)的并行运算:
SHADD16指令:
-
对两个操作数的对应16位半字执行加法
-
将结果算术右移1位(相当于除以2)
-
将处理后的半字结果写入目标寄存器
SHADDB指令:
-
对两个操作数的对应8位字节执行加法
-
将结果算术右移1位(相当于除以2)
-
将处理后的字节结果写入目标寄存器
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
本指令不影响任何状态标志
应用示例
SHADD16 R1, R0 ; R0和R1的半字相加后减半,结果存入R1对应半字
SHADDB R4, R0, R5 ; R0和R5的字节相加后减半,结果存入R4对应字节
3.5.11 SHASX和SHSAX(有符号半字交叉加减并右移)
有符号半减加交换/有符号半减减加交换
语法
参数说明:
-
op 支持以下指令:
-
SHASX:半减加交换(先加后减)
-
SHSAX:半减减加交换(先减后加)
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn/Rm:第一/第二操作数寄存器
功能描述
SHASX指令:
-
将Rn高半字与Rm低半字相加
-
结果右移1位(半减)后写入Rd高半字
-
将Rn低半字与Rm高半字相减
-
结果右移1位(半减)后写入Rd低半字
SHSAX指令:
-
将Rn高半字与Rm低半字相减
-
结果右移1位(半减)后写入Rd低半字
-
将Rn低半字与Rm高半字相加
-
结果右移1位(半减)后写入Rd高半字
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
不影响任何状态标志
应用示例
SHASX R7, R4, R2 ; (R4[31:16]+R2[15:0])>>1 → R7[31:16] ; (R4[15:0]-R2[31:16])>>1 → R7[15:0]

3.5.12 SHSUB16和SHSUB8(有符号半字/字节减法并右移)
有符号半减减法(16位/8位)
语法
参数说明:
-
op 支持以下指令:
-
SHSUB16:16位有符号半减减法
-
SHSUB8:8位有符号半减减法
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:被减数寄存器
-
Rm:减数寄存器
功能描述
实现16位/8位数据相减后右移一位(结果减半)的并行运算:
SHSUB16指令:
-
对两个操作数的对应16位半字执行减法(Rn-Rm)
-
将结果算术右移1位(结果减半)
-
处理后的半字结果写入目标寄存器
SHSUB8指令:
-
对两个操作数的对应8位字节执行减法(Rn-Rm)
-
将结果算术右移1位(结果减半)
-
处理后的字节结果写入目标寄存器
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
不影响任何状态标志
应用示例
SHSUB16 R1, R0 ; 用R0的各个半字减去R1对应半字 ; 结果减半后写回R1对应半字 SHSUB8 R4, R0, R5 ; 用R0的各个字节减去R5对应字节 ; 结果减半后写入R4对应字节
3.5.13 SSUB16和SSUB8(有符号16位/8位减法)
有符号减法(16位/8位)
语法
参数说明:
-
op 为以下指令之一:
-
SSUB16:执行两组16位有符号整数减法
-
SSUB8:执行四组8位有符号整数减法
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:被减数寄存器
-
Rm:减数寄存器
功能描述
SSUB16指令:
-
将Rn的每个半字减去Rm对应的半字
-
将差值结果写入目标寄存器的对应半字
SSUB8指令:
-
将Rn的每个字节减去Rm对应的字节
-
将差值结果写入目标寄存器的对应字节
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
这些指令不会改变任何状态标志
应用示例
SSUB16 R1, R0 ; 用R1的各个半字减去R0对应半字,结果存入R1对应半字 SSUB8 R4, R0, R5 ; 用R0的各个字节减去R5对应字节,结果存入R4对应字节
3.5.14 SASX和SSAX(有符号半字交叉加减)
有符号加交换减/有符号减交换加
语法

参数说明:
-
op 支持以下指令:
-
SASX:有符号加交换减(高半字加,低半字减)
-
SSAX:有符号减交换加(高半字减,低半字加)
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn/Rm:第一/第二操作数寄存器
功能描述
SASX指令:
-
将Rn高半字与Rm低半字执行有符号加法
-
结果写入Rd高半字
-
将Rn低半字与Rm高半字执行有符号减法
-
结果写入Rd低半字
SSAX指令:
-
将Rn高半字与Rm低半字执行有符号减法
-
结果写入Rd低半字
-
将Rn低半字与Rm高半字执行有符号加法
-
结果写入Rd高半字
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
不影响任何状态标志
应用示例
SASX R0, R4, R5 ; 将R4高半位[31:16]与R5低半位[15:0]相加 → R0[31:16] ; 将R4低半位[15:0]减去R5高半位[31:16] → R0[15:0] SSAX R7, R3, R2 ; 将R3低半位[15:0]减去R2高半位[31:16] → R7[15:0] ; 将R3高半位[31:16]与R2低半位[15:0]相加 → R7[31:16]
3.5.15 TST(测试)、TEQ(测试相等)
位测试与等价测试
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行")
-
Rn:存放第一操作数的寄存器
-
Operand2:灵活的第二操作数(选项详见第60页"灵活第二操作数")
功能描述
这些指令测试寄存器值与Operand2的关系,并根据结果更新条件标志位(不保留运算结果):
TST指令:
-
执行Rn与Operand2的按位与操作(功能同ANDS指令,但丢弃结果)
-
测试Rn特定位:设置Operand2对应位为1,其余位为0
TEQ指令:
-
执行Rn与Operand2的按位异或操作(功能同EORS指令,但丢弃结果)
-
测试两值相等性(不影响V/C标志)
-
符号位测试:运算后N标志反映两操作数符号位的异或结果
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
-
根据结果更新N(负标志)和Z(零标志)
-
计算Operand2时可能更新C(进位标志)
-
不影响V(溢出标志)
应用示例
TST R0, #0x3F8 ; 测试R0与0x3F8的按位与,更新APSR但丢弃结果 TEQEQ R10, R9 ; 条件执行:测试R10与R9是否相等,更新APSR但丢弃结果
3.5.16 UADD16和UADD8(无符号16位/8位加法)
无符号加法(16位/8位)
语法
参数说明:
-
op 为以下指令之一:
-
UADD16:执行两组16位无符号整数加法
-
UADDB:执行四组8位无符号整数加法
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
功能描述
UADD16指令:
-
将Rn的每个16位半字与Rm对应半字相加
-
无符号结果写入目标寄存器对应半字
UADDB指令:
-
将Rn的每个8位字节与Rm对应字节相加
-
无符号结果写入目标寄存器对应字节
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
这些指令不会改变任何状态标志
应用示例
UADD16 R1, R0 ; 将R0各半字与R1对应半字相加,结果存入R1 UADDB R4, R0, R5 ; 将R0各字节与R5对应字节相加,结果存入R4
3.5.17 UASX和USAX(无符号半字交叉加减)
无符号加交换减/无符号减交换加
语法
参数说明:
-
op 为以下指令之一:
-
UASX:无符号加交换减(高半字加,低半字减)
-
USAX:无符号减交换加(高半字减,低半字加)
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn/Rm:第一/第二操作数寄存器
功能描述
UASX指令:
-
将Rn高半位[31:16]与Rm低半位[15:0]相加 → Rd[31:16]
-
将Rn低半位[15:0]减去Rm高半位[31:16] → Rd[15:0]
USAX指令:
-
将Rn高半位[31:16]减去Rm低半位[15:0] → Rd[15:0]
-
将Rn低半位[15:0]与Rm高半位[31:16]相加 → Rd[31:16]
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
不影响任何状态标志
应用示例
UASX R0, R4, R5 ; 将R4高半字[31:16]与R5低半字[15:0]相加 → R0[31:16] ; 将R4低半字[15:0]减去R5高半字[31:16] → R0[15:0] USAX R7, R3, R2 ; 将R3高半字[31:16]减去R2低半字[15:0] → R7[15:0] ; 将R3低半字[15:0]与R2高半字[31:16]相加 → R7[31:16]
3.5.18 UHADD16和UHADD8(无符号半字/字节加法并右移)
无符号半减加法(16位/8位)
语法

参数说明:
-
op 为以下指令之一:
-
UHADD16:16位无符号半减加法
-
UHADDB:8位无符号半减加法
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
功能描述
UHADD16指令:
-
将Rn与Rm的对应16位半字相加
-
结果右移1位(数值减半)
-
无符号结果写入目标寄存器对应半字
UHADDB指令:
-
将Rn与Rm的对应8位字节相加
-
结果右移1位(数值减半)
-
无符号结果写入目标寄存器对应字节
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
这些指令不会改变任何状态标志
应用示例
UHADD16 R7, R3 ; R7与R3的半字相加后减半,结果存入R7对应半字 UHADDB R4, R0, R5 ; R0与R5的字节相加后减半,结果存入R4对应字节
3.5.19 UHASX和UHSAX(无符号半字交叉加减并右移)
无符号半减加交换减/无符号半减减交换加
语法
参数说明:
-
op 为以下指令之一:
-
UHASX:无符号半减加交换减(高半字加,低半字减)
-
UHSAX:无符号半减减交换加(高半字减,低半字加)
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn/Rm:第一/第二操作数寄存器
功能描述
UHASX指令:
-
将Rn高半字[31:16]与Rm低半字[15:0]相加 → 结果右移1位 → Rd[31:16]
-
将Rn低半字[15:0]减去Rm高半字[31:16] → 结果右移1位 → Rd[15:0]
UHSAX指令:
-
将Rn高半字[31:16]减去Rm低半字[15:0] → 结果右移1位 → Rd[31:16]
-
将Rn低半字[15:0]与Rm高半字[31:16]相加 → 结果右移1位 → Rd[15:0]
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
不影响任何状态标志
应用示例
UHASX R7, R4, R2 ; (R4[31:16] + R2[15:0])>>1 → R7[31:16] ; (R4[15:0] - R2[31:16])>>1 → R7[15:0]

UHSAX R0, R3, R5 ; 将R3高半字[31:16]减去R5低半字[15:0] → 结果右移1位 → R0[31:16] ; 将R3低半字[15:0]与R5高半字[31:16]相加 → 结果右移1位 → R0[15:0]
3.5.20 UHSUB16和UHSUB8(无符号半字/字节减法并右移)
无符号半减减法(16位/8位)
语法
参数说明:
-
op 为以下指令之一:
-
UHSUB16:执行两组16位无符号整数减法,结果减半后写入目标寄存器
-
UHSUB8:执行四组8位无符号整数减法,结果减半后写入目标寄存器
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:被减数寄存器
-
Rm:减数寄存器
功能描述
UHSUB16指令:
-
将Rn的每个16位半字减去Rm对应半字
-
结果算术右移1位(数值减半)
-
无符号结果写入目标寄存器对应半字
UHSUB8指令:
-
将Rn的每个8位字节减去Rm对应字节
-
结果算术右移1位(数值减半)
-
无符号结果写入目标寄存器对应字节
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
这些指令不会改变任何状态标志
应用示例
UHSUB16 R1, R0 ; R0各半字减去R1对应半字,结果减半后写回R1 UHSUB8 R4, R2, R3 ; R2各字节减去R3对应字节,结果减半后写入R4

UHSUB8 R4, R0, R5 ; 将R0各字节减去R5对应字节,结果减半后写入R4对应字节
3.5.21 SEL(选择)
字节选择指令
语法
参数说明:
-
cond:可选条件码(标准汇编语法字段)
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
功能描述
SEL指令根据APSR.GE标志位的值,从两个操作数中选择字节:
-
读取APSR.GE各位的值
-
根据GE标志位的状态,选择Rn或Rm中的对应字节写入目标寄存器
使用限制
无特殊限制
标志位影响
本指令不会改变任何状态标志
应用示例
SADD16 R0, R1, R2 ; 执行加法并设置GE标志位 SEL R0, R0, R3 ; 根据GE标志选择R0或R3中的字节写入R0
3.5.22 USAD8(无符号绝对差和)
无符号绝对差值和
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
功能描述
USAD8指令执行以下操作:
-
计算Rn与Rm对应字节的无符号差值(Rn-Rm)
-
对所有字节差值的绝对值求和
-
将累加结果写入目标寄存器
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
本指令不会改变任何状态标志
应用示例
USAD8 R1, R4, R0 ; 计算R4与R0各字节绝对差值和,结果存入R1 USAD8 R0, R5 ; 计算R0与R5各字节绝对差值和,结果存回R0
3.5.23 USADA8(无符号绝对差和累加)
无符号绝对差值和累加
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
-
Ra:累加值寄存器
功能描述
USADA8指令执行以下操作:
-
计算Rn与Rm对应字节的无符号差值(Rn-Rm)
-
对所有字节差值的绝对值求和
-
将累加值Ra与绝对差值和相加
-
最终结果写入目标寄存器
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
本指令不会改变任何状态标志
应用示例
USADA8 R1, R0, R6 ; 计算R0与R6字节绝对差值和,加上R1原值,结果存R1 USADA8 R4, R0, R5, R2 ; 计算R0与R5字节绝对差值和,加上R2值,结果存R4
3.5.24 USUB16和USUB8(无符号16位/8位减法)
无符号减法(16位/8位)
语法
参数说明:
-
op 为以下指令之一:
-
USUB16:16位无符号减法
-
USUB8:8位无符号减法
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:被减数寄存器
-
Rm:减数寄存器
功能描述
USUB16指令:
-
将Rn的每个16位半字减去Rm对应半字
-
无符号结果写入目标寄存器对应半字
USUB8指令:
-
将Rn的每个8位字节减去Rm对应字节
-
无符号结果写入目标寄存器对应字节
使用限制
-
禁止使用SP(栈指针)和PC(程序计数器)
标志位影响
这些指令不会改变任何状态标志
应用示例
USUB16 R1, R0 ; R0各半字减去R1对应半字,结果存入R1 USUB8 R4, R0, R5 ; R0各字节减去R5对应字节,结果存入R4
3.6 乘法与除法指令

| 表29. 乘除指令汇总表 | ||
|---|---|---|
| 助记符 | 简要说明 | 详见章节 |
| MLA | 乘加(32位结果) | 第110页 MUL、MLA和MLS |
| MLS | 乘减(32位结果) | 第110页 MUL、MLA和MLS |
| MUL | 乘法(32位结果) | 第110页 MUL、MLA和MLS |
| SDIV | 有符号除法 | 第124页 SDIV和UDIV |
| SMLA[B,T] | 有符号半字乘加 | 第112页 SMLA和SMLAW |
| SMLAD, SMLADX | 有符号双乘加 | 第114页 SMLAD |
| SMLAL | 有符号长乘加(32x32+64,64位结果) | 第115页 SMLAL和SMLALD |
| SMLAL[B,T] | 有符号半字长乘加 | 第115页 SMLAL和SMLALD |
| SMLALD, SMLALDX | 有符号双长乘加 | 第115页 SMLAL和SMLALD |
| SMLAW[B,T] | 有符号字乘半字加 | 第112页 SMLA和SMLAW |
| SMLSD | 有符号双乘减 | 第117页 SMLSD和SMLSLD |
| SMLSLD | 有符号双长乘减 | 第117页 SMLSD和SMLSLD |
| SMMLA | 有符号高位乘加 | 第119页 SMMLA和SMMLS |
| SMMLS, SMMLSR | 有符号高位乘减 | 第119页 SMMLA和SMMLS |
| SMUAD, SMUADX | 有符号双乘加 | 第121页 SMUAD和SMUSD |
| SMUL[B,T] | 有符号字乘半字 | 第122页 SMUL和SMULW |
| SMMUL, SMMULR | 有符号高位乘法 | 第120页 SMMUL |
| SMULL | 有符号长乘法(32x32,64位结果) | 第120页 SMMUL |
| SMULWB, SMULWT | 有符号字乘半字 | 第122页 SMUL和SMULW |
| SMUSD, SMUSDX | 有符号双乘减 | 第121页 SMUAD和SMUSD |
| UDIV | 无符号除法 | 第112页 SMLA和SMLAW |
| UMAAL | 无符号长乘加加(32x32+32+32,64位结果) | 第111页 UMULL、UMAAL和UMLAL |
| UMLAL | 无符号长乘加(32x32+64,64位结果) | 第111页 UMULL、UMAAL和UMLAL |
| UMULL | 无符号长乘法(32x32,64位结果) | 第111页 UMULL、UMAAL和UMLAL |
3.6.1 MUL(乘法)、MLA(乘累加)、MLS(乘减)
32位乘法、乘加与乘减(32位操作数,32位结果)
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行")
-
S:可选后缀。若指定则根据结果更新条件标志位
-
Rd:目标寄存器(若省略则默认为Rn)
-
Rn/Rm:乘数寄存器
-
Ra:累加/减数寄存器
功能描述
MUL指令:
-
计算Rn × Rm,结果的低32位存入Rd
MLA指令:
-
计算 (Rn × Rm) + Ra,结果的低32位存入Rd
MLS指令:
-
计算 Ra - (Rn × Rm),结果的低32位存入Rd
注:运算结果与操作数的有符号性无关
使用限制
-
禁止使用SP和PC
-
若MUL指令带S后缀:
-
所有寄存器必须为R0-R7
-
Rd必须与Rm相同
-
不可使用条件后缀
-
标志位影响
若指定S后缀,MUL指令会:
-
根据结果更新N(负)和Z(零)标志
-
不影响C(进位)和V(溢出)标志
应用示例
MUL R10, R2, R5 ; R10 = R2 × R5 MLA R10, R2, R1, R5 ; R10 = (R2 × R1) + R5 MULS R0, R2, R2 ; R0 = R2² 并更新标志位 MULLT R2, R3, R2 ; 条件执行:R2 = R3 × R2 MLS R4, R5, R6, R7 ; R4 = R7 - (R5 × R6)
3.6.2 UMULL(无符号长乘法)、UMAAL(无符号双累加长乘法)、UMLAL(无符号长乘累加)
无符号长乘法(可选累加),32位操作数生成64位结果
语法
参数说明:
-
op 为以下指令之一:
-
UMULL:无符号长乘法
-
UMAAL:无符号双累加长乘法
-
UMLAL:无符号累加长乘法
-
-
cond:可选条件码(参见第65页"条件执行")
-
RdHi/RdLo:目标寄存器(同时存储累加值)
-
Rn/Rm:第一/第二操作数寄存器
功能描述
UMULL指令:
-
对两个无符号32位整数执行乘法
-
结果的低32位存入RdLo
-
结果的高32位存入RdHi
UMAAL指令:
-
执行两个无符号32位整数乘法
-
将RdHi值加到64位乘积结果
-
再将RdLo值加到当前结果
-
最终结果的高32位存入RdHi
-
最终结果的低32位存入RdLo
UMLAL指令:
-
执行两个无符号整数乘法
-
将64位乘积与RdHi:RdLo的64位值相加
-
结果写回RdHi和RdLo
使用限制
-
禁止使用SP和PC
-
RdHi与RdLo必须为不同寄存器
标志位影响
这些指令不影响任何状态标志
应用示例
3.6.3 SMLA(有符号乘累加)、SMLAW(有符号乘累加半字)
有符号半字乘加,有符号半字乘加指令
语法
参数说明:
-
op 为以下指令类型:
-
SMLA:有符号半字长乘加
-
X/Y指定源寄存器半字选择:
-
B:使用低半字[15:0]
-
T:使用高半字[31:16]
-
-
-
SMLAW:有符号字乘半字加
-
Y指定Rm寄存器半字选择(T/B同上)
-
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器(可省略,默认为Rn)
-
Rn/Rm:乘数寄存器
-
Ra:累加数寄存器
功能描述
SMLA系列指令(SMLABB/SMLABT/SMLATB/SMLATT):
-
按指定选择Rn和Rm的半字进行有符号乘法
-
将32位乘积与Ra值相加
-
结果写入Rd
-
忽略源寄存器未指定的半字
SMLAW系列指令(SMLAWB/SMLAWT):
-
将Rn的32位有符号值与Rm指定半字相乘
-
取48位乘积的高32位与Ra相加
-
结果写入Rd(忽略乘积低16位)
-
若累加发生溢出,则设置APSR的Q标志(乘法不会溢出)
使用限制
-
禁止使用SP和PC
标志位影响
-
若检测到溢出,则设置APSR的Q标志位
应用示例
SMLABB R5, R6, R4, R1 ; R6[15:0] × R4[15:0] + R1 → R5 SMLATB R5, R6, R4, R1 ; R6[31:16] × R4[15:0] + R1 → R5 SMLATT R5, R6, R4, R1 ; R6[31:16] × R4[31:16] + R1 → R5 SMLABT R5, R6, R4, R1 ; R6[15:0] × R4[31:16] + R1 → R5 SMLABT R4, R3, R2 ; R4[15:0] × R3[31:16] + R2 → R4 SMLAWB R10, R2, R5, R3 ; R2 × R5[15:0] + R3(取高32位)→ R10 SMLAWT R10, R2, R1, R5 ; R2 × R1[31:16] + R5(取高32位)→ R10
3.6.4 SMLAD(有符号双乘累加)
有符号双半字乘加指令
语法
参数说明:
-
op 为以下指令类型:
-
SMLAD:有符号双半字乘加
-
SMLADX:有符号双半字反向乘加
-
X指定半字交叉相乘模式(存在时采用高低半字交叉相乘)
-
-
-
cond:可选条件码(参见第65页"条件执行")
-
Rd:目标寄存器
-
Rn:第一操作数寄存器
-
Rm:第二操作数寄存器
-
Ra:累加值寄存器
功能描述
将操作数视为四个16位有符号半字:
标准模式(无X后缀):
-
Rn[31:16] × Rm[31:16] + Rn[15:0] × Rm[15:0]
-
乘积和与Ra相加
-
32位结果写入Rd
交叉模式(X后缀):
-
Rn[31:16] × Rm[15:0] + Rn[15:0] × Rm[31:16]
-
乘积和与Ra相加
-
32位结果写入Rd
使用限制
-
禁止使用SP和PC
标志位影响
不影响任何状态标志
应用示例
SMLAD R10, R2, R1, R5 ; R2[31:16]×R1[31:16] + R2[15:0]×R1[15:0] + R5 → R10 SMLADX R0, R2, R4, R6 ; R2[31:16]×R4[15:0] + R2[15:0]×R4[31:16] + R6 → R0
3.6.5 SMLAL(有符号长乘累加)、SMLALD(有符号双长乘累加)
有符号长乘加指令(支持半字/双半字操作)
语法
参数说明:
-
op 为以下指令类型:
-
SMLAL:有符号长乘加(32位×32位→64位)
-
SMLALXY:有符号半字长乘加(X/Y指定半字选择)
-
B:使用低半字[15:0]
-
T:使用高半字[31:16]
-
-
SMLALD:有符号双半字长乘加
-
SMLALDX:有符号双半字反向长乘加(X存在时交叉相乘)
-
-
cond:可选条件码(参见第65页)
-
RdHi/RdLo:目标寄存器(存储64位结果/累加值)
-
Rn/Rm:操作数寄存器
功能描述
SMLAL指令:
-
对Rn和Rm的有符号32位值执行乘法
-
将64位乘积与RdHi:RdLo的64位值相加
-
结果写回RdHi和RdLo
SMLALXY指令(如SMLALBB/SMLALBT等):
-
按X/Y选择Rn和Rm的半字进行有符号乘法
-
将符号扩展的32位乘积与64位累加值相加
-
结果写回RdHi:RdLo(忽略未选半字)
SMLALD/SMLALDX指令:
-
标准模式(无X):Rn[31:16]×Rm[31:16] + Rn[15:0]×Rm[15:0]
-
交叉模式(X后缀):Rn[31:16]×Rm[15:0] + Rn[15:0]×Rm[31:16]
-
乘积和与64位累加值相加后写回目标寄存器
源寄存器中未指定的半字数据将被忽略
SMLALD和SMLALDX指令将RnRn和RmRm中的值解释为四个半字的16位有符号补码整数。这些指令的功能如下:
-
如果未包含X,则将RnRn的高半字有符号值与RmRm的高半字有符号值相乘,同时将RnRn的低半字有符号值与RmRm的低半字有符号值相乘。
-
如果包含X,则将RnRn的高半字有符号值与RmRm的低半字有符号值相乘,同时将RnRn的低半字有符号值与RmRm的高半字有符号值相乘。
-
将两个乘法结果与RdLoRdLo和RdHtRdHt中的64位有符号值相加,生成最终的64位乘积。
-
将64位乘积写入RdLoRdLo和RdHtRdHt中。
限制条件
在这些指令中:
-
不能使用SP或PC寄存器。
-
RdHtRdHt和RdLoRdLo必须是不同的寄存器。
条件标志位
这些指令不会影响条件码标志位。
示例

| SMLAL | R4, R5, R3, R8 | ; 将R3和R8的值相乘,结果与R5:R4相加后写入R5:R4 |
|---|---|
| SMLALBT | R2, R1, R6, R7 | ; 将R6的低半字与R7的高半字相乘,符号扩展为32位后与R1:R2相加,结果写入R1:R2 |
| SMLALTB | R2, R1, R6, R7 | ; 将R6的高半字与R7的低半字相乘,符号扩展为32位后与R1:R2相加,结果写入R1:R2 |
| SMLALD | R6, R8, R5, R1 | ; 将R5和R1的高半字相乘,低半字相乘,结果与R8:R6相加后写入R8:R6 |
| SMLALDX | R6, R8, R5, R1 | ; 将R5的高半字与R1的低半字相乘,R5的低半字与R1的高半字相乘,结果与R8:R6相加后写入R8:R6 |
3.6.6 SMLSD(有符号双乘减)、SMLSLD(有符号双长乘减)
SMLSD 和 SMLSLD
有符号乘减双半字与有符号长乘减双半字
语法

其中:
-
op是以下指令之一:-
SMLSD:有符号乘减双半字。 -
SMLSDX:有符号乘减双半字(半字交换)。 -
SMLSLD:有符号长乘减双半字。 -
SMLSLDX:有符号长乘减双半字(半字交换)。 -
如果包含
X,则乘法操作为“低半字 × 高半字”和“高半字 × 低半字”。 -
如果省略
X,则乘法操作为“低半字 × 低半字”和“高半字 × 高半字”。
-
-
cond是可选的条件码(参见第65页的“条件执行”)。 -
Rd是目标寄存器。 -
Rn、Rm是存放第一和第二操作数的寄存器。 -
Ra是存放累加值的寄存器。
操作
SMLSD 指令 将第一和第二操作数的值解释为四个有符号半字。该指令执行以下操作:
-
可选地交换第二操作数的半字顺序。
-
执行两次有符号 16 × 16 位半字乘法。
-
将高半字乘法的结果从低半字乘法的结果中减去。
-
将减法结果与有符号累加值相加。
-
将加法结果写入目标寄存器。
SMLSLD 指令 将 Rn 和 Rm 的值解释为四个有符号半字。该指令执行以下操作:
-
可选地交换第二操作数的半字顺序。
-
执行两次有符号 16 × 16 位半字乘法。
-
将高半字乘法的结果从低半字乘法的结果中减去。
-
将减法结果与
RdHi和RdLo中的64位值相加。 -
将64位加法结果写入
RdHi和RdLo。
限制条件
在这些指令中:
-
不能使用
SP或PC寄存器。
条件标志位
-
如果累加操作溢出,该指令会设置
Q标志位。 -
在乘法或减法操作期间不会发生溢出。
对于Thumb指令集,这些指令不会影响条件码标志位。
示例

SMLSD R0, R4, R5, R6
; 将R4的低半字与R5的低半字相乘,R4的高半字与R5的高半字相乘,
; 用第一个乘积减去第二个乘积,再加上R6的值,最终结果写入R0
SMLSDX R1, R3, R2, R0
; 将R3的低半字与R2的高半字相乘,R3的高半字与R2的低半字相乘,
; 用第一个乘积减去第二个乘积,再加上R0的值,最终结果写入R1
SMLSLD R3, R6, R2, R7
; 将R6的低半字与R2的低半字相乘,R6的高半字与R2的高半字相乘,
; 用第一个乘积减去第二个乘积,再加上R6:R3的值,最终结果写入R6:R3
SMLSLDX R3, R6, R2, R7
; 将R6的低半字与R2的高半字相乘,R6的高半字与R2的低半字相乘,
; 用第一个乘积减去第二个乘积,再加上R6:R3的值,最终结果写入R6:R3
3.6.7 SMMLA(有符号矩阵乘累加)、SMMLS(有符号矩阵乘减)
SMMLA 和 SMMLS
有符号高字乘加与有符号高字乘减
语法

其中:
-
op为以下指令之一:-
SMMLA:有符号高字乘加 -
SMMLS:有符号高字乘减
-
-
R为舍入标志。若指定 R,则结果将进行舍入而非截断,即在提取高字前先给乘积加上 0x80000000 -
cond为可选条件码(参见第65页"条件执行") -
Rd为目标寄存器 -
Rn、Rm为存放乘法操作数的寄存器 -
Ra为存放累加值的寄存器
操作
SMMLA指令 将 Rn 和 Rm 的值解释为有符号32位字:
-
对 Rn 和 Rm 的值进行乘法运算
-
可选地通过加 0x80000000 对结果进行舍入
-
提取结果的最高有效32位
-
将 Ra 的值与提取的有符号值相加
-
将加法结果写入 Rd
SMMLS指令 将 Rn 和 Rm 的值解释为有符号32位字:
-
对 Rn 和 Rm 的值进行乘法运算
-
可选地通过加 0x80000000 对结果进行舍入
-
提取结果的最高有效32位
-
从 Ra 的值中减去提取的结果值
-
将减法结果写入 Rd
限制条件
这些指令中:
-
不能使用 SP 或 PC 寄存器
条件标志位
这些指令不影响条件码标志位
示例


SMMLA R0, R4, R5, R6 ; 将 R4 和 R5 相乘,提取高32位,
; 加上 R6,截断后写入 R0
SMMLAR R6, R2, R1, R4 ; 将 R2 和 R1 相乘,提取高32位,
; 加上 R4,舍入后写入 R6
SMMLSR R3, R6, R2, R7 ; 将 R6 和 R2 相乘,提取高32位,
; 减去 R7,舍入后写入 R3
3.6.8 SMMUL(有符号矩阵乘法)
SMMUL
有符号高字乘法
语法

其中:
• op 为以下指令之一:
-
SMMUL:有符号高字乘法 -
R:舍入标志。若指定R,则结果将进行舍入而非截断。此时会在提取高字前给乘积加上常量0x80000000
•cond为可选条件码(参见第65页"条件执行")
•Rd为目标寄存器
•Rn、Rm为存放操作数的寄存器
操作
SMMUL指令将Rn和Rm的值解释为32位有符号补码整数。该指令执行以下操作:
-
对Rn和Rm的值进行乘法运算
-
可选地对结果进行舍入,否则执行截断
-
将结果的最高有效32位有符号值写入Rd
限制条件
本指令中:
-
不得使用SP或PC寄存器
条件标志位
本指令不影响条件码标志位
示例

SMMUL R0, R4, R5 ; 将R4和R5相乘,截取高32位
; 并写入R0
SMMULR R6, R2, R1 ; 将R6和R2相乘,对高32位舍入
; 并写入R6
3.6.9 SMUAD(有符号双乘加)、SMUSD(有符号双乘减)
SMUAD 和 SMUSD
有符号双半字乘加与有符号双半字乘减
语法

其中:
• op 为以下指令之一:
-
SMUAD:有符号双半字乘加 -
SMUADX:有符号双半字乘加(半字交换) -
SMUSD:有符号双半字乘减 -
SMUSDX:有符号双半字乘减(半字交换) -
若包含
X,则执行"低半字×高半字"和"高半字×低半字"乘法 -
若省略
X,则执行"低半字×低半字"和"高半字×高半字"乘法
•cond为可选条件码(参见第65页"条件执行")
•Rd为目标寄存器
•Rn、Rm为存放操作数的寄存器
操作
SMUAD指令 将操作数解释为两个有符号半字:
-
可选地交换第二操作数的半字顺序
-
执行两次有符号16×16位乘法
-
将两个乘法结果相加
-
将加法结果写入目标寄存器
SMUSD指令 将操作数值解释为有符号补码整数:
-
可选地交换第二操作数的半字顺序
-
执行两次有符号16×16位乘法
-
从低半字乘法结果中减去高半字乘法结果
-
将减法结果写入目标寄存器
限制条件
这些指令中:
-
不得使用SP或PC寄存器
条件标志位
-
若加法溢出则设置Q标志位(乘法操作不会产生溢出)
示例


SMUAD R0, R4, R5 ; 将R4低半字与R5低半字相乘,加上
; R4高半字与R5高半字的乘积,结果写入R0
SMUADX R3, R7, R4 ; 将R7低半字与R4高半字相乘,加上
; R7高半字与R4低半字的乘积,结果写入R3
3.6.10 SMUL(有符号乘法)、SMULW(有符号乘半字)
有符号乘法(半字)与有符号乘法(字×半字)
语法

op为以下指令之一:
-
SMUL(XY):有符号乘法(半字)
-
X和Y指定源寄存器Rn和Rm中用作乘数的半字:
-
X=B:使用Rn的底半字(位[15:0])
-
X=T:使用Rn的顶半字(位[31:16])
-
Y=B:使用Rm的底半字(位[15:0])
-
Y=T:使用Rm的顶半字(位[31:16])
-
-
-
SMULW(Y):有符号乘法(字×半字)
-
Y指定源寄存器Rm中用作第二个乘数的半字:
-
Y=B:使用Rm的底半字(位[15:0])
-
Y=T:使用Rm的顶半字(位[31:16])
-
-
-
cond为可选条件码(参见第65页"条件执行") -
Rd为目标寄存器 -
Rn、Rm为存放操作数的寄存器
操作
SMULBB/SMULTB/SMULBT/SMULTT指令
将Rn和Rm的值解释为四个有符号16位整数:
-
对Rn和Rm指定的有符号半字(顶/底)执行乘法
-
将32位乘法结果写入Rd
SMULWT/SMULWB指令
将Rn解释为32位有符号整数,Rm解释为两个16位有符号半字:
-
将第一个操作数与第二个操作数的顶半字(T后缀)或底半字(B后缀)相乘
-
将48位结果的最高有效32位写入目标寄存器
限制条件
不得使用SP或PC寄存器
示例
3.6.11 UMULL(无符号长乘法)、UMLAL(无符号长乘累加)、SMULL(有符号长乘法)、SMLAL(有符号长乘累加)
32位操作数的有符号/无符号长乘法(可选累加),产生64位结果
语法

其中:
• op 为以下指令之一:
-
UMULL:无符号长乘法 -
UMLAL:无符号长乘法(带累加) -
SMULL:有符号长乘法 -
SMLAL:有符号长乘法(带累加)
•cond为可选条件码(参见第65页"条件执行")
•RdHi, RdLo为目标寄存器,对于UMLAL和SMLAL也用于存放累加值
•Rn,Rm为存放操作数的寄存器
操作
UMULL指令
将Rn和Rm的值解释为无符号整数:
-
对两数执行乘法运算
-
将结果的低32位存入RdLo,高32位存入RdHi
UMLAL指令
将Rn和Rm的值解释为无符号整数:
-
对两数执行乘法运算
-
将64位乘积与RdHi:RdLo中的无符号64位值相加
-
将累加结果写回RdHi和RdLo
SMULL指令
将Rn和Rm的值解释为二进制补码有符号整数:
-
对两数执行乘法运算
-
将结果的低32位存入RdLo,高32位存入RdHi
SMLAL指令
将Rn和Rm的值解释为二进制补码有符号整数:
-
对两数执行乘法运算
-
将64位乘积与RdHi:RdLo中的有符号64位值相加
-
将累加结果写回RdHi和RdLo
限制条件
使用这些指令时:
• 不可使用SP或PC寄存器
• RdHi和RdLo必须是不同的寄存器
条件标志位
这些指令不会影响条件码标志位
示例
UMULL R0, R4, R5, R6 ; 无符号乘法:(R4,R0) = R5 × R6 SMLAL R4, R5, R3, R8 ; 有符号乘累加:(R5,R4) = (R5,R4) + R3 × R8
3.6.12 SDIV(有符号除法)、UDIV(无符号除法)
SDIV 和 UDIV
有符号除法与无符号除法
语法
其中:
-
cond为可选条件码(参见第65页"条件执行") -
Rd为目标寄存器。若省略,则目标寄存器为Rn -
Rn为被除数寄存器 -
Rm为除数寄存器
操作
-
SDIV:对Rn中的有符号整数执行除以Rm值的运算
-
UDIV:对Rn中的无符号整数执行除以Rm值的运算
对于两条指令:
-
若Rn值无法被Rm整除,结果向零取整
限制条件
-
不可使用SP或PC寄存器
条件标志位
-
这些指令不会改变标志位
示例
SDIV R0, R2, R4 ; 有符号除法:R0 = R2 / R4 UDIV R8, R8, R1 ; 无符号除法:R8 = R8 / R1
3.7 饱和指令
本节介绍饱和指令。

表30. 饱和指令
| 助记符 | 简要描述 | 参考 |
|---|---|---|
| SSAT | 有符号饱和 | 第126页的SSAT和USAT |
| SSAT16 | 有符号半字饱和 | 第127页的SSAT16和USAT16 |
| USAT | 无符号饱和 | 第126页的SSAT和USAT |
| USAT16 | 无符号半字饱和 | 第127页的SSAT16和USAT16 |
| QADD | 饱和加法 | 第128页的QADD和QSUB |
| QSUB | 饱和减法 | 第128页的QADD和QSUB |
| QSUB16 | 饱和减法16位 | 第128页的QADD和QSUB |
| QASX | 饱和加法与减法(带交换) | 第129页的QASX和QSAX |
| QSAX | 饱和减法与加法(带交换) | 第129页的QASX和QSAX |
| QDADD | 饱和双倍并加法 | 第130页的QDADD和QDSUB |
| QDSUB | 饱和双倍并减法 | 第130页的QDADD和QDSUB |
| UQADD16 | 无符号饱和加法16位 | 第132页的UQADD和UQSUB |
| UQADDB | 无符号饱和加法8位 | 第132页的UQADD和UQSUB |
| UQASX | 无符号饱和加法与减法(带交换) | 第131页的UQASX和UQSAX |
| UQSAX | 无符号饱和减法与加法(带交换) | 第131页的UQASX和UQSAX |
| UQSUB16 | 无符号饱和减法16位 | 第132页的UQADD和UQSUB |
| UQSUBB | 无符号饱和减法8位 | 第132页的UQADD和UQSUB |
对于有符号的nn位饱和操作,规则如下:
-
如果待饱和的值小于-2n−12n−1,则返回的结果为-2n−12n−1;
-
如果待饱和的值大于2n−1−12n−1−1,则返回的结果为2n−1−12n−1−1;
-
否则,返回的结果与待饱和的值相同。
对于无符号的nn位饱和操作,规则如下:
-
如果待饱和的值小于0,则返回的结果为0;
-
如果待饱和的值大于2n−12n−1,则返回的结果为2n−12n−1;
-
否则,返回的结果与待饱和的值相同。
如果返回的结果与待饱和的值不同,则称为饱和。如果发生饱和,指令会将APSR中的Q标志设置为1;否则,Q标志保持不变。要将Q标志清零为0,必须使用MSR指令,详见第187页的MSR。
要读取Q标志的状态,可使用MRS指令,详见第186页的MRS。
3.7.1 SSAT(有符号饱和) 和 USAT(无符号饱和)
有符号饱和和无符号饱和到任意位位置,可在饱和前进行可选移位操作。
语法

其中: * `op` 是以下之一: - SSAT:将有符号值饱和到有符号范围。 - USAT:将有符号值饱和到无符号范围。 * `cond` 是可选的条件码(参见第65页的“条件执行”)。 * `Rd` 是目标寄存器。 * `n` 指定饱和的位位置: - 对于 SSAT,n 的范围是 1 到 32。 - 对于 USAT,n 的范围是 0 到 31。 * `Rm` 是包含待饱和值的寄存器。 * `shift #s` 是可选的在饱和前应用于 `Rm` 的移位操作,可以是以下之一: - ASR #s:其中 s 的范围是 1 到 31(算术右移)。 - LSL #s:其中 s 的范围是 0 到 31(逻辑左移)。
操作
这些指令将值饱和到有符号或无符号的 n 位范围。
-
SSAT 指令:先应用指定的移位,然后将值饱和到有符号范围:
−2n−1≤x≤2n−1−1−2n−1≤x≤2n−1−1 -
USAT 指令:先应用指定的移位,然后将值饱和到无符号范围:
0≤x≤2n−10≤x≤2n−1
限制
-
不能使用 SP(栈指针)和 PC(程序计数器)。
条件标志
-
这些指令不会影响条件码标志(如 N、Z、C、V)。
-
如果发生饱和,这些指令会将 Q 标志设置为 1。
示例
SSAT R7, #16, R7, LSL #4 ; 将 R7 中的值逻辑左移 4 位,然后
; 将其饱和为有符号 16 位值,并写回 R7
USATNE R0, #7, R5 ; 条件性地将 R5 中的值饱和为无符号 7 位值,
; 并写入 R0
3.7.2 SSAT16(有符号半字饱和) 和 USAT16(无符号半字饱和)
对两个半字(halfword)执行有符号或无符号饱和到指定位位置的操作。
语法
其中:
-
op是以下之一:-
SSAT16:将有符号半字值饱和到有符号范围。
-
USAT16:将有符号半字值饱和到无符号范围。
-
-
cond是可选的条件码(参见第65页的“条件执行”)。 -
Rd是目标寄存器。 -
n指定饱和的位位置:-
对于 SSAT16,
n的范围是 1 到 16。 -
对于 USAT16,
n的范围是 0 到 15。
-
-
Rm是包含待饱和值的寄存器。
操作
-
SSAT16 指令:
-
对寄存器中两个有符号 16 位半字值,按
n指定的位位置进行饱和处理。 -
将结果作为两个有符号 16 位半字写入目标寄存器。
-
-
USAT16 指令:
-
对寄存器中两个无符号 16 位半字值,按
n指定的位位置进行饱和处理。 -
将结果作为两个无符号半字写入目标寄存器。
-
限制
-
不能使用
SP(栈指针)和PC(程序计数器)。
条件标志
-
这些指令不会影响条件码标志(如 N、Z、C、V)。
-
如果发生饱和,这些指令会将
Q标志设置为 1。
示例
SSAT16 R7, #9, R2 ; 将 R2 中的高半字和低半字分别饱和为
; 9 位有符号值,并写入 R7 的对应半字
USAT16NE R0, #13, R5 ; 条件性地将 R5 中的高半字和低半字
; 饱和为 13 位无符号值,并写入 R0 的对应半字
3.7.3 QADD(饱和加法) 和 QSUB(饱和减法)
有符号饱和加法与饱和减法
语法

其中:
-
op是以下之一:-
QADD:32 位饱和加法
-
QADD8:四个 8 位整数的饱和加法
-
QADD16:两个 16 位整数的饱和加法
-
QSUB:32 位饱和减法
-
QSUB8:四个 8 位整数的饱和减法
-
QSUB16:两个 16 位整数的饱和减法
-
-
cond是可选的条件码(参见第 65 页的“条件执行”)。 -
Rd是目标寄存器。 -
Rn和Rm是存放第一和第二操作数的寄存器。
操作
这些指令对两个、四个或八个值进行加法或减法运算,并将结果饱和到有符号范围后写入目标寄存器。
-
QADD 和 QSUB 指令执行加法或减法后,将结果饱和到有符号范围:
−2n−1≤x≤2n−1−1−2n−1≤x≤2n−1−1其中,
n由指令的位数决定(32、16 或 8)。
如果返回的结果与待饱和的值不同,则称为饱和。如果发生饱和,QADD 和 QSUB 指令会将 APSR 中的 Q 标志设置为 1;否则,Q 标志保持不变。
-
8 位和 16 位的 QADD 和 QSUB 指令 始终不改变 Q 标志。
要清除 Q 标志为 0,必须使用 MSR 指令(参见第 187 页的 MSR)。
要读取 Q 标志的状态,可使用 MRS 指令(参见第 186 页的 MRS)。
限制
-
不能使用 SP(栈指针)和 PC(程序计数器)。
条件标志
-
这些指令不会影响条件码标志(如 N、Z、C、V)。
-
如果发生饱和,这些指令会将 Q 标志设置为 1。
示例


1. 饱和加法指令(16位半字)
QADD16 R7, R4, R2 ; 将寄存器R4和R2中的对应半字相加,
; 结果饱和到16位有符号范围后,
; 写入R7的对应半字
2. 饱和加法指令(8位字节)
QADD8 R3, R1, R6 ; 将寄存器R1和R6中的对应字节相加,
; 结果饱和到8位有符号范围后,
; 写入R3的对应字节
3. 饱和减法指令(16位半字)
QSUB16 R4, R2, R3 ; 从寄存器R2的半字中减去R3的对应半字,
; 结果饱和到16位有符号范围后,
; 写入R4的对应半字
4. 饱和减法指令(8位字节)
QSUB8 R4, R2, R5 ; 从寄存器R2的字节中减去R5的对应字节,
; 结果饱和到8位有符号范围后,
; 写入R4的对应字节
3.7.4 QASX(有符号半字交叉饱和加减) 和 QSAX(有符号半字交叉饱和减加)
带交换的饱和加减法与带交换的饱和减加法(有符号)
语法
其中:
-
op是以下之一:-
QASX:带交换的加法与减法并饱和
-
QSAX:带交换的减法与加法并饱和
-
-
cond是可选的条件码(参见第65页的“条件执行”) -
Rd是目标寄存器 -
Rn和Rm是存放操作数的寄存器
操作
QASX指令:
-
将第一个操作数的高半字与第二个操作数的低半字相加
-
从第一个操作数的低半字中减去第二个操作数的高半字
-
将减法结果饱和到16位有符号范围(-32768 ≤ x ≤ 32767),写入目标寄存器的低半字
-
将加法结果饱和到16位有符号范围(-32768 ≤ x ≤ 32767),写入目标寄存器的高半字
QSAX指令:
-
从第一个操作数的高半字中减去第二个操作数的低半字
-
将第一个操作数的低半字与第二个操作数的高半字相加
-
将加法结果饱和到16位有符号范围(-32768 ≤ x ≤ 32767),写入目标寄存器的低半字
-
将减法结果饱和到16位有符号范围(-32768 ≤ x ≤ 32767),写入目标寄存器的高半字
限制
-
不能使用SP(栈指针)和PC(程序计数器)
条件标志
这些指令不会影响条件码标志
示例
3.7.5 QDADD(双饱和加法) 和 QDSUB(双饱和减法)
有符号的饱和双倍加法与饱和双倍减法
语法
op{cond} {Rd}, Rm, Rn
其中:
-
op是以下之一:-
QDADD:饱和双倍加法
-
QDSUB:饱和双倍减法
-
-
cond是可选的条件码(参见第65页的“条件执行”) -
Rd是目标寄存器 -
Rn和Rm是存放操作数的寄存器
操作
QDADD指令:
-
将第二个操作数(
Rm)的值双倍化(乘以2) -
将双倍化后的结果与第一个操作数(
Rn)的值相加 -
将最终结果写入目标寄存器(
Rd)
QDSUB指令:
-
将第二个操作数(
Rm)的值双倍化(乘以2) -
从第一个操作数(
Rn)的值中减去双倍化后的结果 -
将最终结果写入目标寄存器(
Rd)
饱和处理:
-
双倍化和加法/减法的结果均饱和到32位有符号整数范围(−231≤x≤231−1−231≤x≤231−1)
-
若任一操作(双倍化或加减法)发生饱和,则会将APSR中的Q标志置1
限制
-
不能使用SP(栈指针)和PC(程序计数器)
条件标志
-
若发生饱和,这些指令会将Q标志设置为1
示例


QDADD R7, R4, R2 ; 将R4的值双倍化并饱和到32位,
; 然后与R2相加,结果饱和到32位后写入R7
QDSUB R0, R3, R5 ; 将R5的值双倍化并饱和到32位,
; 然后从R3中减去该值,结果饱和到32位后写入R0
3.7.6 UQASX(无符号半字交叉饱和加减) 和 UQSAX(无符号半字交叉饱和减加)
无符号的带交换饱和加减法与带交换饱和减加法
语法
其中:
-
op是以下之一:-
UQASX:带交换的无符号饱和加减法
-
UQSAX:带交换的无符号饱和减加法
-
-
cond是可选的条件码(参见第65页的"条件执行") -
Rd是目标寄存器 -
Rn和Rm是存放操作数的寄存器
操作
UQASX指令:
-
将第一个操作数(
Rn)的低半字与第二个操作数(Rm)的高半字相加 -
从第一个操作数(
Rn)的高半字中减去第二个操作数(Rm)的低半字 -
将加法结果饱和到16位无符号范围(0 ≤ x ≤ 65535),写入目标寄存器(
Rd)的高半字 -
将减法结果饱和到16位无符号范围(0 ≤ x ≤ 65535),写入目标寄存器(
Rd)的低半字
UQSAX指令:
-
从第一个操作数(
Rn)的高半字中减去第二个操作数(Rm)的低半字 -
将第一个操作数(
Rn)的低半字与第二个操作数(Rm)的高半字相加 -
将减法结果饱和到16位无符号范围(0 ≤ x ≤ 65535),写入目标寄存器(
Rd)的高半字 -
将加法结果饱和到16位无符号范围(0 ≤ x ≤ 65535),写入目标寄存器(
Rd)的低半字
限制
-
不能使用SP(栈指针)和PC(程序计数器)
条件标志
-
这些指令不会影响条件码标志(N/Z/C/V)
示例
UQASX R7, R4, R2 ; 将R4的低半字与R2的高半字相加,
; 结果饱和到16位无符号数后写入R7的高半字;
; 从R4的高半字减去R2的低半字,
; 结果饱和到16位无符号数后写入R7的低半字
UQSAX R0, R3, R5 ; 从R3的高半字减去R5的低半字,
; 结果饱和到16位无符号数后写入R0的高半字;
; 将R3的低半字与R5的高半字相加,
; 结果饱和到16位无符号数后写入R0的低半字
3.7.7 UQADD(无符号饱和加法) 和 UQSUB(无符号饱和减法)
无符号饱和加法与减法
语法
其中:
-
op是以下之一:-
UQADD8:四个8位无符号整数的饱和加法
-
UQADD16:两个16位无符号整数的饱和加法
-
UQSUB8:四个8位无符号整数的饱和减法
-
UQSUB16:两个16位无符号整数的饱和减法
-
-
cond是可选的条件码(参见第65页的"条件执行") -
Rd是目标寄存器 -
Rn和Rm是存放操作数的寄存器
操作
UQADD16指令:
-
将第一个操作数(
Rn)和第二个操作数(Rm)的对应高/低半字相加 -
将每个半字的加法结果饱和到16位无符号范围(0 ≤ x ≤ 65535)
UQADD8指令:
-
将第一个操作数(
Rn)和第二个操作数(Rm)的四个对应字节相加 -
将每个字节的加法结果饱和到8位无符号范围(0 ≤ x ≤ 255)
UQSUB16指令:
-
从第一个操作数(
Rn)的半字中减去第二个操作数(Rm)的对应半字 -
将每个半字的减法结果饱和到16位无符号范围(0 ≤ x ≤ 65535)
UQSUB8指令:
-
从第一个操作数(
Rn)的字节中减去第二个操作数(Rm)的对应字节 -
将每个字节的减法结果饱和到8位无符号范围(0 ≤ x ≤ 255)
限制
-
不能使用SP(栈指针)和PC(程序计数器)
条件标志
-
这些指令不会影响条件码标志(N/Z/C/V)
示例
UQADD16 R7, R4, R2 ; 将R4和R2的对应半字相加,
; 结果饱和到16位无符号数后写入R7
UQADD8 R4, R2, R5 ; 将R2和R5的对应字节相加,
; 结果饱和到8位无符号数后写入R4
UQSUB16 R6, R3, R0 ; 从R3的半字中减去R0的对应半字,
; 结果饱和到16位无符号数后写入R6
UQSUB8 R1, R5, R6 ; 从R5的字节中减去R6的对应字节,
; 结果饱和到8位无符号数后写入R1
3.8 打包与解包指令
表31 展示了用于数据打包与解包操作的指令:

| 助记符 | 简要描述 | 参考 |
|---|---|---|
| PKH | 半字打包 | 第135页的PKHBT和PKHTB |
| SXTAB | 8位有符号扩展至32位并加法 | 第137页的SXTA和UXTA |
| SXTAB16 | 双8位有符号扩展至16位并加法 | 第137页的SXTA和UXTA |
| SXTAH | 16位有符号扩展至32位并加法 | 第137页的SXTA和UXTA |
| SXTB | 字节有符号扩展 | 第136页的SXT和UXT |
| SXTB16 | 双8位有符号扩展至16位 | 第136页的SXT和UXT |
| SXTH | 半字有符号扩展 | 第136页的SXT和UXT |
| UXTAB | 8位无符号扩展至32位并加法 | 第137页的SXTA和UXTA |
| UXTAB16 | 双8位无符号扩展至16位并加法 | 第137页的SXTA和UXTA |
| UXTAH | 16位无符号扩展至32位并加法 | 第137页的SXTA和UXTA |
| UXTB | 字节无符号扩展 | 第136页的SXT和UXT |
| UXTB16 | 双8位无符号扩展至16位 | 第136页的SXT和UXT |
| UXTH | 半字无符号扩展 | 第136页的SXT和UXT |
3.8.1 PKHBT(低位打包) 和 PKHTB(高位打包)
半字打包指令
语法
其中:
-
op是以下之一:-
PKHBT:半字打包(低位+高位带移位)
-
PKHTB:半字打包(高位+低位带移位)
-
-
cond是可选的条件码(参见第65页的"条件执行") -
Rd是目标寄存器 -
Rn是第一个操作数寄存器 -
Rm是第二个操作数寄存器(可带移位操作) -
imm是移位长度,具体取决于指令类型:-
PKHBT:LSL左移(1~31位,0表示不移位)
-
PKHTB:ASR算术右移(1~32位,32位移位编码为0b00000)
-
操作
PKHBT指令:
-
将第一个操作数(
Rn)的低半字写入目标寄存器(Rd)的低半字 -
将第二个操作数(
Rm)移位后的值写入目标寄存器(Rd)的高半字
PKHTB指令:
-
将第一个操作数(
Rn)的高半字写入目标寄存器(Rd)的高半字 -
将第二个操作数(
Rm)移位后的值写入目标寄存器(Rd)的低半字
限制
-
Rd不能是栈指针(SP)或程序计数器(PC)
条件标志
-
该指令不会改变任何状态标志
示例
PKHBT R3, R4, R5 LSL #0 ; 将R4的低半字写入R3的低半字,
; 将R5的高半字(不移位)写入R3的高半字
PKHTB R4, R0, R2 ASR #1 ; 将R2算术右移1位后写入R4的低半字,
; 将R0的高半字写入R4的高半字
3.8.2 SXT(有符号扩展) 和 UXT(无符号扩展)
有符号扩展与零扩展
语法
其中:
-
op是以下之一:-
SXTB:将8位值有符号扩展至32位
-
SXTH:将16位值有符号扩展至32位
-
SXTB16:将两个8位值有符号扩展至两个16位值
-
UXTB:将8位值零扩展至32位
-
UXTH:将16位值零扩展至32位
-
UXTB16:将两个8位值零扩展至两个16位值
-
-
cond是可选的条件码(参见第65页的"条件执行") -
Rd是目标寄存器 -
Rm是存放待扩展值的寄存器 -
ROR #n是可选循环右移操作:-
ROR #8:值右移8位 -
ROR #16:值右移16位 -
ROR #24:值右移24位 -
若省略,则不进行移位
-
操作
这些指令执行以下步骤:
-
将
Rm的值循环右移0、8、16或24位 -
从结果中提取指定位并进行扩展:
-
SXTB:提取位[7:0]并有符号扩展至32位
-
UXTB:提取位[7:0]并零扩展至32位
-
SXTH:提取位[15:0]并有符号扩展至32位
-
UXTH:提取位[15:0]并零扩展至32位
-
SXTB16:提取位[7:0]和位[23:16],分别有符号扩展至16位
-
UXTB16:提取位[7:0]和位[23:16],分别零扩展至16位
-
限制
-
不能使用SP(栈指针)和PC(程序计数器)
条件标志
-
这些指令不会影响任何状态标志
示例
SXTH R4, R6, ROR #16 ; 将R6的值循环右移16位,
; 提取结果的低半字并**有符号扩展**至32位,
; 写入R4
UXTB R3, R10 ; 提取R10的最低字节,
; **零扩展**至32位后写入R3
3.8.3 SXTA(有符号扩展并累加) 和 UXTA(无符号扩展并累加)
有符号/无符号扩展并加法指令
语法
其中:
-
op是以下之一:-
SXTAB:8位有符号扩展至32位并加法
-
SXTAH:16位有符号扩展至32位并加法
-
SXTAB16:双8位有符号扩展至16位并加法
-
UXTAB:8位无符号扩展至32位并加法
-
UXTAH:16位无符号扩展至32位并加法
-
UXTAB16:双8位无符号扩展至16位并加法
-
-
cond是可选条件码(参见第65页"条件执行") -
Rd是目标寄存器 -
Rn是第一操作数寄存器 -
Rm是待移位扩展的寄存器 -
ROR #n可选循环右移:-
ROR #8:右移8位 -
ROR #16:右移16位 -
ROR #24:右移24位 -
省略时不移位
-
操作流程
-
循环右移:将
Rm的值右移0/8/16/24位 -
位提取与扩展:
-
SXTAB/UXTAB:提取位[7:0],有符号/零扩展至32位
-
SXTAH/UXTAH:提取位[15:0],有符号/零扩展至32位
-
SXTAB16/UXTAB16:
-
提取位[7:0]和位[23:16]
-
分别有符号/零扩展至16位
-
-
-
加法运算:将扩展后的值与
Rn对应位相加,结果存入Rd
限制
-
禁止使用 SP(栈指针)和 PC(程序计数器)
条件标志
-
不影响任何状态标志
示例
SXTAH R4, R8, R6, ROR #16 ; 将R6循环右移16位,提取低半字
; 有符号扩展至32位后与R8相加,结果存入R4
UXTAB R3, R4, R10 ; 提取R10最低字节,零扩展至32位
; 与R4相加后结果存入R3
3.9 位域操作指令
表32 展示了用于寄存器相邻位集合或位域操作的指令:

| 助记符 | 功能描述 | 参考章节 |
|---|---|---|
| BFC | 位域清零 | 第139页 BFC和BFI |
| BFI | 位域插入 | 第139页 BFC和BFI |
| SBFX | 有符号位域提取 | 第140页 SBFX和UBFX |
| SXTB | 字节有符号扩展 | 第141页 SXT和UXT |
| SXTH | 半字有符号扩展 | 第141页 SXT和UXT |
| UBFX | 无符号位域提取 | 第140页 SBFX和UBFX |
| UXTB | 字节零扩展 | 第141页 SXT和UXT |
| UXTH | 半字零扩展 | 第141页 SXT和UXT |
3.9.1 BFC(位段清零) 和 BFI(位段插入)
位域清零与位域插入
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行") -
Rd:目标寄存器 -
Rn:源寄存器(仅BFI指令使用) -
#lsb:位域最低有效位位置(0-31) -
#width:位域宽度(1至32-lsb)
操作说明
-
BFC指令:
清除目标寄存器中指定的位域。将Rd寄存器从lsb位开始的连续width位清零,其他位保持不变。 -
BFI指令:
将源寄存器的位域插入目标寄存器。用Rn寄存器从第0位开始的width位,替换Rd寄存器中从lsb位开始的width位,其他位保持不变。
使用限制
-
禁止使用 SP(栈指针)和 PC(程序计数器)
条件标志
-
这些指令不会影响任何状态标志
应用示例
BFC R5, #8, #12 ; 将R5的第8至19位(共12位)清零
; 其他位保持不变
BFI R9, R2, #8, #12 ; 将R2的第0至11位复制到R9的第8至19位
; R9的其他位保持不变
3.9.2 SBFX(有符号位段提取) 和 UBFX(无符号位段提取)
有符号位域提取与无符号位域提取
语法
参数说明:
-
cond:可选条件码(参见第65页"条件执行") -
Rd:目标寄存器(32位) -
Rn:源寄存器 -
#lsb:位域最低有效位位置(0-31) -
#width:位域宽度(1至32-lsb)
操作说明
-
SBFX指令:
-
从
Rn中提取lsb位开始的width位 -
有符号扩展至32位
-
结果写入
Rd
-
-
UBFX指令:
-
从
Rn中提取lsb位开始的width位 -
零扩展至32位
-
结果写入
Rd
-
使用限制
-
禁止使用 SP(栈指针)和 PC(程序计数器)
条件标志
-
这些指令不会影响任何状态标志
应用示例
SBFX R0, R1, #20, #4 ; 提取R1的第20-23位(4位)
; 有符号扩展至32位后写入R0
UBFX R8, R11, #9, #10 ; 提取R11的第9-18位(10位)
; 零扩展至32位后写入R8
3.9.3 SXT(有符号扩展) 和 UXT(无符号扩展)
有符号扩展与零扩展
语法
参数说明:
-
extend扩展类型:-
B:8位值扩展至32位
-
H:16位值扩展至32位
-
-
cond:可选条件码(参见第65页"条件执行") -
Rd:目标寄存器(可省略,默认为Rm) -
Rm:待扩展值的源寄存器 -
ROR #n:可选循环右移(8/16/24位)
操作流程
-
循环右移(可选):
-
将
Rm的值右移8/16/24位
-
-
位提取与扩展:
-
SXTB:提取位[7:0] → 有符号扩展至32位
-
UXTB:提取位[7:0] → 零扩展至32位
-
SXTH:提取位[15:0] → 有符号扩展至32位
-
UXTH:提取位[15:0] → 零扩展至32位
-
使用限制
-
禁止使用 SP(栈指针)和 PC(程序计数器)
条件标志
-
不影响任何状态标志
应用示例
SXTH R4, R6, ROR #16 ; 1. 将R6循环右移16位
; 2. 提取结果的低16位
; 3. 有符号扩展至32位后写入R4
UXTB R3, R10 ; 1. 提取R10的最低字节(不移位)
; 2. 零扩展至32位后写入R3
3.9.4 分支与控制指令

| 助记符 | 功能描述 | 参考章节 |
|---|---|---|
| B | 无条件分支 | 第142页 B/BL/BX/BLX |
| BL | 带链接的分支(保存返回地址) | 第142页 B/BL/BX/BLX |
| BLX | 带链接的间接分支 | 第142页 B/BL/BX/BLX |
| BX | 间接分支 | 第142页 B/BL/BX/BLX |
| CBNZ | 非零比较分支 | 第144页 CBZ/CBNZ |
| CBZ | 零值比较分支 | 第144页 CBZ/CBNZ |
| IT | 条件执行块(If-Then) | 第145页 IT指令 |
| TBB | 字节查表分支 | 第147页 TBB/TBH |
| TBH | 半字查表分支 | 第147页 TBB/TBH |
3.9.5 B(分支)、BL(带链接分支)、BX(分支交换) 和 BLX(带链接分支交换)
分支指令
语法

其中:
-
“B”表示分支(立即寻址)。
-
“BL”表示带链接的分支(立即寻址)。
-
“BX”表示间接分支(寄存器寻址)。
-
“BLX”表示带链接的间接分支(寄存器寻址)。
-
“cond”为可选条件码,详见第65页的“条件执行”部分。
-
“label”为PC相对表达式,参见第65页的“PC相对表达式”说明。
-
“Rm”为寄存器,用于指定分支目标地址。Rm值的B[i][0]位必须为1,但实际分支目标地址需通过将该位改为0生成。
操作
这些指令均会跳转至 label(标签)或 Rm 寄存器指定的地址。此外:
-
BL 和 BLX 指令会将下一条指令的地址写入 LR(链接寄存器,即 R14)。
-
若 Rm 的 bit[0] 为 0,BX 和 BLX 指令会触发 UsageFault 异常。
条件分支的特殊规则
-
B cond label 是唯一既可在 IT 块内也可在 IT 块外使用的条件分支指令。
-
其他所有分支指令在 IT 块内必须为条件指令,在 IT 块外则必须为无条件指令(详见第 145 页的 IT 指令说明)。
表 34. 分支跳转范围

| 指令 | 跳转范围 |
|---|---|
| B label | ~16 MB 至 +16 MB |
| Bcond label(IT 块外) | ~1 MB 至 +1 MB |
| Bcond label(IT 块内) | ~16 MB 至 +16 MB |
| BL(cond) label | ~16 MB 至 +16 MB |
| BX(cond) Rm | 寄存器中的任意值 |
| BLX(cond) Rm | 寄存器中的任意值 |
注:为达到最大跳转范围,可能需要使用 .W 后缀(详见第 68 页的指令宽度选择部分)。
限制条件
使用分支指令时需遵守以下限制:
-
BLX 指令中禁止使用 PC(程序计数器)。
-
对于 BX 和 BLX 指令,Rm 的 bit[0] 必须为 1 以确保正确执行,但实际跳转的目标地址需将 bit[0] 改为 0。
-
若这些指令位于 IT 块内,则必须作为 IT 块的最后一条指令。
B 指令是唯一无需强制位于 IT 块内的条件分支指令,但在 IT 块内使用时,其跳转范围更大。
条件标志位
这些指令不会改变处理器的标志位。
示例


B loopA ; 跳转至 loopA
BLE ng ; 条件跳转至标签 ng(若满足条件 LE)
B.W target ; 跳转至 target(16MB 范围内)
BEQ target ; 条件跳转至 target(若满足条件 EQ)
BEQ.W target ; 条件跳转至 target(1MB 范围内)
BL func ; 带链接跳转(调用函数 func),返回地址存入 LR
BX LR ; 从函数调用返回
BXNE R0 ; 条件跳转至 R0 中存储的地址(若满足条件 NE)
BLX R0 ; 带链接的间接跳转(调用 R0 中存储的地址)
3.9.6 CBZ(为零跳转) 和 CBNZ(非零跳转)
零比较跳转与非零比较跳转
语法
参数说明:
-
Rn:存放操作数的寄存器。
-
label:跳转目标地址。
功能
CBZ 和 CBNZ 指令可在不改变条件标志位的前提下实现条件跳转,减少指令数量。
-
CBZ Rn, label 功能等价于(但不影响标志位):
CMP Rn, #0 BEQ label -
CBNZ Rn, label 功能等价于(但不影响标志位):
CMP Rn, #0 BNE label
限制条件
-
Rn 必须为 R0~R7 范围内的寄存器。
-
跳转目标地址必须在指令后 4~130 字节范围内。
-
禁止在 IT 块内使用这两条指令。
条件标志位
这些指令不会改变处理器的标志位。
示例

CBZ R5, target ; 若 R5 为 0,则向前跳转至 target CBNZ R0, target ; 若 R0 不为 0,则向前跳转至 target
3.9.7 IT(条件执行块)
If-Then 条件执行指令
语法
参数说明:
-
x:指定 IT 块中第二条指令的条件开关(
T或E)。 -
y:指定 IT 块中第三条指令的条件开关(
T或E)。 -
z:指定 IT 块中第四条指令的条件开关(
T或E)。 -
cond:指定 IT 块中第一条指令的条件(如
EQ、NE等)。
条件开关选项:
-
T(Then):应用与
cond相同的条件。 -
E(Else):应用
cond的相反条件。
特殊规则:
若cond为 AL(无条件执行),则 IT 块内所有指令必须为无条件指令,且x、y、z只能为T或省略(不可为E)。
功能
-
IT 指令将后续 1~4 条指令转换为条件执行指令,形成 IT 块。
-
IT 块内指令的条件可以是相同或逻辑相反的(通过
T/E指定)。 -
IT 块内的每条指令(包括分支指令)必须在其语法中显式指定
{cond}条件。 -
BKPT 指令在 IT 块内始终执行(即使条件不满足)。
汇编器支持:
部分汇编器可自动生成所需的 IT 指令,无需手动编写(详见具体汇编器文档)。
异常处理
-
异常可在 IT 指令与 IT 块之间或 IT 块内部触发,此时处理器会进入异常处理程序,并在
LR和堆栈的PSR中保存正确的返回信息。 -
通过异常返回指令(如
BX LR)可正常恢复执行,继续处理 IT 块。注:这是唯一允许通过修改 PC 跳转至 IT 块内指令的场景。
限制条件
IT 块内禁止使用以下指令:
-
IT(嵌套 IT 指令)。
-
CBZ 和 CBNZ(零比较跳转指令)。
-
CPSID 和 CPSIE(中断屏蔽指令)。
IT 块的其他限制条件
1. 分支与 PC 修改指令的限制
-
禁止在 IT 块内部使用分支或修改 PC 的指令,除非它们是 IT 块的最后一条指令。
受影响的指令包括:-
ADD PC, PC, Rm -
MOV PC, Rm -
B,BL,BX,BLX -
任何写入 PC 的
LDM、LDR或POP指令 -
TBB和TBH
-
-
禁止跳转至 IT 块内的指令(异常返回除外)。
2. 条件指令的规则
-
除 B{cond} 外,所有条件指令必须位于 IT 块内。
-
B{cond} 可位于 IT 块内外,但在 IT 块内时跳转范围更大。
-
-
IT 块内每条指令的条件后缀必须与其他指令的条件相同或逻辑相反。
3. 汇编器额外限制
部分汇编器可能禁止在 IT 块内使用汇编伪指令(如宏或数据定义)。
条件标志位
IT 指令不会改变处理器的标志位。
示例

示例 1:ITTE 块(3 条件指令)
ITTE NE ; 后续 3 条指令为条件执行
ANDNE R0, R0, R1 ; ANDNE 不更新标志位
ADDSNE R2, R2, #1 ; ADDSNE 更新标志位
MOVEQ R2, R3 ; 条件移动(EQ 是 NE 的反条件)
示例 2:ITE 块(2 条件指令)
CMP R0, #9 ; 将 R0 的十六进制值(0~15)转换为 ASCII
ITE GT ; 后续 2 条指令为条件执行
ADDGT R1, R0, #55 ; 0xA~0xF → 'A'~'F'
ADDLE R1, R0, #48 ; 0x0~0x9 → '0'~'9'
示例 3:IT 块(单条件指令)
IT GT ; 仅 1 条条件指令
ADDGT R1, R1, #1 ; 条件递增 R1
示例 4:ITTEE 块(4 条件指令)
ITTEE EQ ; 后续 4 条指令为条件执行
MOVEQ R0, R1 ; 条件移动
ADDEQ R2, R2, #10 ; 条件加法
ANDNE R3, R3, #1 ; 条件 AND(NE 是 EQ 的反条件)
BNE.W dloop ; 分支指令必须为 IT 块的最后一条指令
错误示例:缺少条件后缀
IT NE ; 下一条指令应为条件指令 ADD R0, R0, R1 ; 语法错误:IT 块内指令未指定条件后缀
3.9.8 TBB(表跳转字节) 和 TBH(表跳转半字)
字节表跳转与半字表跳转
语法
参数说明:
-
Rn 是包含分支长度表地址的寄存器。
如果 Rn 是 PC,则表的地址为紧跟在 TBB 或 TBH 指令后的字节地址。 -
Rm 是索引寄存器,包含表中的索引值。对于半字表,LSL #1 会将 Rm 中的值翻倍,以形成表中的正确偏移量。
操作
这些指令使用单字节偏移表(TBB)或半字偏移表(TBH)实现 PC 相对前向分支。Rn 提供指向表的指针,Rm 提供表中的索引值。对于 TBB,分支偏移量为表中返回的无符号字节值的两倍;对于 TBH,分支偏移量为表中返回的无符号半字值的两倍。分支跳转的目标地址为:紧跟在 TBB 或 TBH 指令后的字节地址加上该偏移量。
限制条件
-
Rn 不能为 SP(栈指针)。
-
Rm 不能为 SP 或 PC。
-
在 IT 块内使用时,必须作为最后一条指令。
条件标志位
这些指令不会改变处理器的标志位。
示例


1. TBB 字节表跳转
ADR.W R0, BranchTable_Byte ; 加载跳转表基址到 R0
TBB [R0, R1] ; 根据 R1 的索引跳转
; 各分支标签
Case1:
; 指令序列
Case2:
; 指令序列
Case3:
; 指令序列
; 跳转表定义(字节偏移量)
BranchTable_Byte:
DCB 0 ; Case1 偏移量(0 ×2 = 0,跳转到 Case1)
DCB ((Case2 - Case1)/2) ; Case2 偏移量(相对 Case1 的字节差 ÷2)
DCB ((Case3 - Case1)/2) ; Case3 偏移量
2. TBH 半字表跳转
TBH [PC, R1, LSL #1] ; 使用 PC 作为表基址,R1 索引 ×2 ; 跳转表定义(半字偏移量) BranchTable_H: DCI ((CaseA - BranchTable_H)/2) ; CaseA 偏移量 DCI ((CaseB - BranchTable_H)/2) ; CaseB 偏移量 DCI ((CaseC - BranchTable_H)/2) ; CaseC 偏移量 ; 各分支标签 CaseA: ; 指令序列 CaseB: ; 指令序列 CaseC: ; 指令序列
3.10 浮点指令
(前置说明)本指令集仅在系统包含并启用浮点运算单元(FPU)时可用。关于FPU启用方法,请参见第257页"启用浮点运算单元"章节。

| 助记符 | 功能描述 | 详细说明页数 |
|---|---|---|
| VABS | 浮点绝对值运算 | 第151页 VABS |
| VADD | 浮点加法运算 | 第152页 VADD |
| VCMP | 浮点寄存器比较(或与零值比较) | 第153页 VCMP/VCMPE |
| VCMPE | 带无效操作检查的浮点比较 | 第153页 VCMP/VCMPE |
| VCVT | 浮点与整型转换 | 第154页 VCVT/VCVTR |
| VCVT | 浮点与定点数转换 | 第155页 浮点-定点转换 |
| VCVTR | 带舍入的浮点-整型转换 | 第154页 VCVT/VCVTR |
| VCVTB | 半精度转单精度 | 第156页 VCVTB/VCVTT |
| VCVTT | 单精度转半精度 | 第156页 VCVTB/VCVTT |
| VDIV | 浮点除法运算 | 第157页 VDIV |
| VFMA | 浮点融合乘加运算 | 第158页 VFMA/VFMS |
| VFNMA | 浮点融合负乘加运算 | 第159页 VFNMA/VFNMS |
| VFMS | 浮点融合乘减运算 | 第158页 VFMA/VFMS |
| VFNMS | 浮点融合负乘减运算 | 第159页 VFNMA/VFNMS |
| VLDM | 扩展寄存器批量加载 | 第160页 VLDM |
| VLDR | 内存到扩展寄存器的单次加载 | 第161页 VLDR |
| VLMA | 浮点乘加运算 | 第162页 VLMA/VLMS |
| VLMS | 浮点乘减运算 | 第162页 VLMA/VLMS |
| VMOV | 浮点立即数传输 | 第163页 立即数传输 |
| VMOV | 浮点寄存器间传输 | 第164页 寄存器传输 |
| VMOV | ARM核心寄存器→单精度标量 | 第165页 标量传输 |
| VMOV | 双ARM寄存器→双单精度 | 第166页 寄存器到单精度 |
| VMOV | ARM寄存器与标量间传输 | 第167页 双寄存器传输 |
| VMOV | 标量→ARM核心寄存器 | 第168页 标量到寄存器 |
| VMRS | 浮点系统寄存器→ARM核心寄存器 | 第169页 VMRS |

| 助记符 | 功能描述 | 详细说明页数 |
|---|---|---|
| VMSR | ARM核心寄存器→浮点系统寄存器传输 | 第170页 VMSR |
| VMUL | 浮点乘法运算 | 第171页 VMUL |
| VNEG | 浮点取负运算 | 第172页 VNEG |
| VNMLA | 浮点乘加运算(带取负) | 第173页 VNMLA/VNMLS/VNMUL |
| VNMLS | 浮点乘减运算(带取负) | 第173页 VNMLA/VNMLS/VNMUL |
| VNMUL | 浮点乘法运算(带取负) | 第173页 VNMLA/VNMLS/VNMUL |
| VPOP | 扩展寄存器出栈操作 | 第174页 VPOP |
| VPUSH | 扩展寄存器入栈操作 | 第175页 VPUSH |
| VSQRT | 浮点平方根运算 | 第176页 VSQRT |
| VSTM | 扩展寄存器批量存储 | 第177页 VSTM |
| VSTR | 扩展寄存器→内存单次存储 | 第178页 VSTR |
| VSUB | 浮点减法运算 | 第179页 VSUB |
3.10.1 VABS(浮点绝对值)
浮点绝对值运算
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Sd:目标浮点寄存器
-
Sm:操作数浮点寄存器
操作流程
-
计算操作数寄存器(Sm)中浮点数值的绝对值
-
将结果存入目标寄存器(Sd)
使用限制
本指令无特殊使用限制
浮点状态标志
-
符号位(sign bit)强制清零
应用示例

VABS.F32 S4, S6 ; 计算S6寄存器的绝对值,结果存入S4
3.10.2 VADD(浮点加法)
浮点加法指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Sd:目标浮点寄存器(可省略,默认为Sn)
-
Sn, Sm:操作数浮点寄存器
操作原理
-
对两个操作数寄存器(Sn与Sm)执行单精度浮点加法运算
-
运算结果存入目标寄存器(Sd)
使用限制
本指令无特殊架构限制
浮点状态标志
该指令不影响任何状态标志位
典型应用

VADD.F32 S4, S6, S7 ; 计算S6+S7,结果存入S4
3.10.3 VCMP(浮点比较), VCMPE(带异常的浮点比较)
3.10.3 VCMP/VCMPE
浮点比较指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
E:
-
存在时:任何NaN操作数触发无效操作异常
-
不存在时:仅信号型NaN触发异常
-
-
Sd:待比较浮点寄存器
-
Sm:比较基准浮点寄存器(或立即数0.0)
操作特性
-
支持两种比较模式:
-
两个浮点寄存器间比较
-
浮点寄存器与零值比较
-
-
比较结果写入浮点状态控制寄存器(FPSCR)标志位
异常触发
-
任意操作数为NaN时可能触发无效操作异常
-
操作数为信号型NaN时必定触发异常
标志位传递
需配合VMRS指令(第169页)将FPSCR标志位传输至ARM状态寄存器
应用示例

VCMP.F32 S4, #0.0 ; S4寄存器与零值比较
VCMP.F32 S4, S2 ; S4与S2寄存器比较
3.10.4 VCVT(浮点与整数转换), VCVTR(浮点与整数舍入转换)
浮点与整型转换指令
语法

参数说明:
-
R:
-
存在时:采用FPSCR指定的舍入模式
-
不存在时:采用"向零舍入"模式(仅浮点转整型时生效)
-
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Tm:数据类型标识符:
-
S32:有符号32位整型
-
U32:无符号32位整型
-
-
Sd/Sm:目标寄存器/操作数寄存器
转换方向
-
浮点→整型转换(.F32.Tm语法):
-
默认采用向零舍入
-
带R后缀时采用FPSCR舍入模式
-
-
整型→浮点转换(.Tm.F32语法):
-
强制采用FPSCR舍入模式
-
技术特性
-
转换结果存入目标寄存器Sd
-
整型转换范围:32位有符号/无符号数值
状态标志
本指令不影响任何状态标志位
3.10.5 VCVT(浮点与定点转换)
浮点与定点数转换指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Td:定点数数据类型:
-
S16:有符号16位
-
U16:无符号16位
-
S32:有符号32位
-
U32:无符号32位
-
-
Sd:目标寄存器和操作数寄存器
-
fbits:定点数小数位宽:
-
16位类型:0-16位
-
32位类型:1-32位
-
转换特性
-
浮点→定点转换(.F32.Td语法):
-
采用"向零舍入"模式
-
有符号类型执行符号扩展
-
无符号类型执行零扩展
-
-
定点→浮点转换(.Td.F32语法):
-
采用"就近舍入"模式
-
仅使用源寄存器的低位有效位
-
技术规范
-
浮点精度:单精度(.F32)
-
定点数范围:16/32位有符号/无符号
-
小数位宽动态可调(fbits参数)
状态标志
本指令不影响任何状态标志位
3.10.6 VCVTB(底部半精度转换), VCVTT(顶部半精度转换)
半精度与单精度浮点转换指令
语法

参数说明:
-
y:操作数区域选择位:
-
B:使用寄存器低16位([15:0])
-
T:使用寄存器高16位([31:16])
-
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Sd:目标寄存器
-
Sm:操作数寄存器
转换操作
-
半精度→单精度转换(.F16.F32后缀):
-
从Sm寄存器指定区域(高/低16位)提取半精度值
-
转换为单精度浮点数后存入Sd寄存器
-
-
单精度→半精度转换(.F32.F16后缀):
-
将Sm寄存器单精度值转换为半精度
-
结果写入Sd寄存器指定区域(高/低16位),保留另一区域原始值
-
技术特性
-
支持寄存器高低位选择(通过B/T后缀)
-
半精度浮点符合IEEE 754标准
-
转换过程保持非目标区域数据不变
状态标志
本指令不影响任何状态标志位
3.10.7 VDIV(浮点除法)
浮点除法指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Sd:目标寄存器(可省略,默认为Sn)
-
Sn:被除数寄存器
-
Sm:除数寄存器
运算规则
-
执行单精度浮点除法运算:Sn ÷ Sm
-
运算结果存入目标寄存器Sd
限制
无限制
状态标志
本指令不影响任何状态标志位
3.10.8 VFMA(浮点乘加), VFMS(浮点乘减)
浮点融合乘加/乘减指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Sd:目标寄存器(可省略,默认为Sn)
-
Sn/Sm:操作数寄存器
运算流程
VFMA指令:
-
执行单精度浮点乘法:Sn × Sm
-
将乘积与Sd值累加(不进行中间舍入)
VFMS指令:
-
对Sn操作数取负
-
执行单精度浮点乘法:-Sn × Sm
-
将乘积与Sd值相加(不进行中间舍入)
技术特性
-
采用融合乘加运算(FMA)架构
-
中间结果不单独舍入,提高计算精度
-
符合IEEE 754-2008标准
状态标志
本指令不影响任何状态标志位
3.10.9 VFNMA(浮点负乘加), VFNMS(浮点负乘减)
浮点融合负乘加/乘减指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Sd:目标寄存器(可省略,默认为Sn)
-
Sn/Sm:操作数寄存器
运算流程
VFNMA指令:
-
对第一操作数取负:-Sn
-
执行单精度浮点乘法:-Sn × Sm
-
将目标寄存器值取负后与乘积相加:-Sd + (-Sn × Sm)
-
结果存入目标寄存器
VFNMS指令:
-
执行单精度浮点乘法:Sn × Sm
-
将目标寄存器值取负后与乘积相加:-Sd + (Sn × Sm)
-
结果存入目标寄存器
技术特性
-
采用融合运算架构(不进行中间结果舍入)
-
支持单精度浮点运算(.F32)
-
符合IEEE 754-2008标准
状态标志
本指令不影响任何状态标志位
3.10.10 VLDM(浮点多寄存器加载)
浮点多寄存器加载指令
语法

参数说明:
-
mode 寻址模式:
-
IA(Increment After):从Rn指定地址开始顺序加载
-
DB(Decrement Before):在Rn指定地址前结束加载
-
-
cond:可选条件码(参见第65页条件执行章节)
-
size:可选数据位宽(32/64位)
-
Rn:基址寄存器(可使用SP堆栈指针)
-
!:回写标志(DB模式必须启用,IA模式可选)
-
list:目标寄存器列表(需用花括号包裹的连续编号寄存器,如{S0-S3})
操作特性
-
从基址寄存器指定的连续内存地址加载多个浮点寄存器
-
支持单精度(32位)/双精度(64位)数据加载
使用限制
-
数据位宽必须与寄存器类型匹配:
-
32位对应单精度寄存器
-
64位对应双精度寄存器
-
-
寄存器列表限制:
-
至少包含1个寄存器
-
双精度寄存器最多16个
-
-
DB模式必须启用地址回写(!标志)
状态标志
本指令不影响任何状态标志位
3.10.11 VLDR(浮点单寄存器加载)
浮点单寄存器加载指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
.64/.32:数据位宽标识符(双精度/单精度)
-
Dd:双精度目标寄存器
-
Sd:单精度目标寄存器
-
Rn:基址寄存器(支持SP堆栈指针)
-
imm:立即数偏移量(取值范围0-1020的4的倍数)
-
label:字面量数据标签
操作特性
-
从内存加载单个浮点寄存器
-
支持三种寻址模式:
-
基址寄存器+偏移量
-
字面量直接加载
-
PC相对寻址
-
技术规范
-
立即数偏移量需4字节对齐(imm%4=0)
-
支持正负偏移(±1020范围内)
-
双精度操作使用D寄存器,单精度使用S寄存器
状态标志
本指令不影响任何状态标志位
3.10.12 VLMA(浮点乘加加载), VLMS(浮点乘减加载)
浮点乘加/乘减指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标寄存器(同时作为累加操作数)
-
Sn/Sm:乘法操作数寄存器
运算逻辑
VLMA指令:
-
执行单精度浮点乘法:Sn × Sm
-
将乘积与Sd寄存器值相加:Sd + (Sn × Sm)
VLMS指令:
-
执行单精度浮点乘法:Sn × Sm
-
从Sd寄存器值减去乘积:Sd - (Sn × Sm)
技术特性
-
支持单精度浮点运算(.F32后缀)
-
符合IEEE 754标准
-
目标寄存器同时作为输入/输出操作数
状态标志
本指令不影响任何状态标志位
3.10.13 VMOV(立即数浮点传输)
浮点立即数传输指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标浮点寄存器
-
#imm:浮点型立即数常量
操作特性
-
将指定的浮点立即数加载到目标寄存器
-
支持单精度浮点格式(.F32)
技术规范
-
立即数必须符合IEEE 754单精度浮点格式
-
支持条件执行
状态标志
本指令不影响任何状态标志位
3.10.14 VMOV(寄存器间浮点传输)
浮点寄存器间数据传输指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Dd/Dm:双精度目标/源寄存器(64位)
-
Sd/Sm:单精度目标/源寄存器(32位)
操作特性
-
实现浮点寄存器间的数据直接拷贝
-
支持双精度(.F64)和单精度(.F32)格式
技术规范
-
源寄存器与目标寄存器位宽必须匹配
-
支持条件执行
状态标志
本指令不影响任何状态标志位
3.10.15 VMOV(标量到Arm核寄存器传输)
双精度浮点寄存器分段传输指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Rt:目标ARM核心寄存器(禁止PC/SP)
-
Dn:源双精度浮点寄存器(64位)
-
x:数据段选择位:
-
0:传输低32位(Dn[31:0])
-
1:传输高32位(Dn[63:32])
-
操作特性
-
实现双精度浮点寄存器的分段传输
-
支持高低位选择(通过x参数控制)
-
数据从浮点单元传输至核心寄存器组
使用限制
-
目标寄存器禁止为程序计数器(PC)或堆栈指针(SP)
状态标志
本指令不影响任何状态标志位
3.10.16 VMOV(Arm核寄存器到单精度传输)
语法格式
参数说明
-
cond:可选条件执行码(详见第65页条件执行章节)
-
Sn:32位单精度浮点寄存器
-
Rt:ARM核心通用寄存器(不可使用PC或SP)
功能特性
-
实现ARM核心寄存器与浮点单元间的数据双向传输
-
支持条件执行(通过cond参数控制)
-
数据格式为IEEE 754单精度浮点数
重要约束
-
禁止使用程序计数器(PC)和堆栈指针(SP)作为目标寄存器
状态标志影响
本指令执行不会改变任何状态标志位
3.10.17 VMOV(双Arm核寄存器到双单精度传输)
语法规范
关键参数
-
cond:可选条件码(参见第65页条件执行)
-
Sm/Sm+1:连续编号的单精度寄存器对
-
Rt/Rt2:ARM核心寄存器(允许非连续编号)
操作特性
-
实现两组寄存器间的批量数据传输:
-
模式1:浮点寄存器对→核心寄存器对
-
模式2:核心寄存器对→浮点寄存器对
-
-
支持条件执行
重要约束
-
浮点寄存器必须连续编号(Sm+1自动关联)
-
核心寄存器允许任意组合(无需连续)
-
禁止使用PC/SP作为目标寄存器
状态标志
本指令执行不影响处理器状态标志
3.10.18 VMOV(Arm核寄存器到标量传输)
核心寄存器到双精度浮点寄存器的分段传输指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
.32:可选数据位宽标识符(固定32位传输)
-
Dd[x]:目标双精度寄存器段选择:
-
0:写入低32位(Dd[31:0])
-
1:写入高32位(Dd[63:32])
-
-
Rt:源ARM核心寄存器(禁止PC/SP)
操作特性
-
将核心寄存器的32位数据写入双精度浮点寄存器的指定区段
-
非目标区段数据保持不变
技术限制
-
源寄存器禁止为程序计数器(PC)或堆栈指针(SP)
-
必须严格遵循32位对齐传输
状态标志
本指令不影响任何处理器状态标志
3.10.19 VMRS(浮点状态寄存器到Arm核寄存器传输)
浮点系统寄存器到ARM核心寄存器的传输指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Rt:目标核心寄存器(R0-R14,禁止PC/SP)
-
FPSCR:浮点状态与控制寄存器(源寄存器)
-
APSR_nzcv:应用程序状态寄存器标志位组
操作模式
-
寄存器传输模式:
-
完整复制FPSCR寄存器值到目标通用寄存器
-
-
标志位传输模式:
-
选择性同步FPSCR的N/Z/C/V标志到APSR
-
技术限制
-
目标寄存器禁止为PC或SP
-
标志位传输仅影响APSR的N/Z/C/V位
状态标志影响
-
寄存器传输模式:不影响任何标志位
-
标志位传输模式:更新APSR的N/Z/C/V标志
3.10.20 VMSR(Arm核寄存器到浮点状态寄存器传输)
ARM核心寄存器到浮点系统寄存器的传输指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
FPSCR:目标浮点状态与控制寄存器
-
Rt:源通用寄存器(R0-R14,禁止PC/SP)
操作特性
-
将核心寄存器的32位数据传输至FPSCR寄存器
-
完整覆盖FPSCR所有控制位和状态位
技术限制
-
源寄存器禁止使用程序计数器(PC)或堆栈指针(SP)
-
数据传输过程不可逆
状态更新
-
更新FPSCR寄存器的内容
3.10.21 VMUL(浮点乘法)
浮点乘法指令
语法
参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标寄存器(可省略,默认为Sn)
-
Sn/Sm:乘数操作数寄存器
运算规则
-
执行单精度浮点乘法运算:Sn × Sm
-
运算结果存入目标寄存器Sd
技术特性
-
符合IEEE 754单精度浮点运算标准
-
支持条件执行
-
目标寄存器可选(缺省时替换首个操作数)
状态标志
本指令不影响任何状态标志位
3.10.22 VNEG(浮点取负)
浮点取负指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标浮点寄存器
-
Sm:源浮点操作数寄存器
运算逻辑
-
对源寄存器(Sm)的浮点数值执行取负操作
-
结果存入目标寄存器(Sd)
-
实质操作:反转浮点数的符号位(符合IEEE 754标准)
技术特性
-
支持单精度浮点运算(.F32后缀)
-
符号位反转不影响数值位和指数位
状态标志
本指令不影响任何状态标志位
3.10.23 VNMLA(浮点负乘加), VNMLS(浮点负乘减), VNMUL(浮点负乘)
浮点融合乘加/乘减/乘取负指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标寄存器(VNMUL可缺省)
-
Sn/Sm:乘数操作数寄存器
运算逻辑
VNMLA指令:
-
计算:-(Sn × Sm) + (-Sd)
-
结果回写至Sd
VNMLS指令:
-
计算:(Sn × Sm) + (-Sd)
-
结果回写至Sd
VNMUL指令:
-
计算:-(Sn × Sm)
-
结果存入Sd(缺省时替换Sn)
技术特性
-
全系列支持单精度浮点(.F32)
-
符合IEEE 754标准运算规则
-
VNMUL支持目标寄存器缺省模式
状态标志
本系列指令不影响任何状态标志位
3.10.24 VPOP(浮点出栈)
浮点扩展寄存器出栈指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
.size:可选数据位宽标识符:
-
32:单精度(对应S寄存器)
-
64:双精度(对应D寄存器)
-
-
list:寄存器列表(需用花括号包裹的连续编号寄存器,如{S0-S3})
操作特性
-
从堆栈内存连续加载多个浮点寄存器
-
自动递增堆栈指针(隐含回写)
-
支持单/双精度混合加载(需匹配.size声明)
使用限制
-
寄存器列表必须满足:
-
至少包含1个寄存器
-
最多16个双精度寄存器
-
-
数据位宽必须与寄存器类型匹配
状态标志
本指令不影响任何状态标志位
3.10.25 VPUSH(浮点压栈)
浮点扩展寄存器入栈指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
.size:可选数据位宽标识符:
-
32:单精度(对应S寄存器)
-
64:双精度(对应D寄存器)
-
-
list:寄存器列表(需用花括号包裹的连续编号寄存器,如{D0-D3})
操作特性
-
将多个连续浮点寄存器值压入堆栈
-
自动递减堆栈指针(隐含地址回写)
-
支持单/双精度混合存储(需匹配.size声明)
使用限制
-
寄存器列表必须满足:
-
至少包含1个寄存器
-
最多16个双精度寄存器
-
-
数据位宽必须与寄存器类型严格对应
状态标志
本指令执行不影响任何处理器状态标志
3.10.26 VSORT(浮点排序)
浮点平方根运算指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标浮点寄存器(存储计算结果)
-
Sm:源浮点操作数寄存器
运算特性
-
计算源寄存器(Sm)中单精度浮点数的平方根
-
结果写入目标寄存器(Sd)
-
符合IEEE 754标准运算规则
技术规范
-
支持单精度浮点运算(.F32后缀)
-
自动处理非数值(NaN)和无穷大(Infinity)特殊情况
-
支持条件执行
状态标志
本指令不影响任何状态标志位
3.10.27 VSTM(浮点多寄存器存储)
浮点多寄存器存储指令
语法

参数说明
-
mode 寻址模式:
-
IA(默认):从Rn地址开始顺序存储(可省略)
-
DB:在Rn地址前结束存储
-
-
cond:可选条件码(参见第65页条件执行章节)
-
.size:数据位宽标识符(32/64位,需与寄存器类型匹配)
-
Rn:基址寄存器(支持SP堆栈指针)
-
!:地址回写标志(DB模式必须启用)
-
list:寄存器列表(如{S0-S3}或{D1,D3})
操作特性
-
将多个连续浮点寄存器值存入连续内存地址
-
支持两种地址更新方式:
-
IA模式:先存储后递增地址
-
DB模式:先递减地址后存储
-
使用限制
-
寄存器列表要求:
-
至少包含1个寄存器
-
双精度寄存器最多16个
-
-
禁止使用PC作为基址寄存器
状态标志
本指令不影响任何状态标志位
3.10.28 VSTR(浮点单寄存器存储)
浮点单寄存器存储指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
.32/.64:数据位宽标识符(需与寄存器类型匹配)
-
Sd/Dd:源浮点寄存器(单/双精度)
-
Rn:基址寄存器(支持SP堆栈指针)
-
imm:立即数偏移量(±1020范围内4的倍数,可缺省)
操作特性
-
将浮点寄存器值存储至内存地址:
-
计算地址:
[Rn + imm](imm缺省时为[Rn])
-
-
支持两种精度模式:
-
单精度模式(.32):占用4字节内存
-
双精度模式(.64):占用8字节内存
-
使用限制
-
禁止使用PC作为基址寄存器
-
地址必须按4字节对齐
状态标志
本指令不影响任何状态标志位
3.10.29 VSUB(浮点减法)
浮点减法指令
语法

参数说明
-
cond:可选条件码(参见第65页条件执行章节)
-
Sd:目标寄存器(可省略,默认为Sn)
-
Sn:被减数寄存器
-
Sm:减数寄存器
运算规则
-
执行单精度浮点减法运算:Sn - Sm
-
结果存入目标寄存器Sd
技术特性
-
符合IEEE 754单精度浮点标准
-
支持条件执行
-
目标寄存器可选(缺省时替换首个操作数)
状态标志
本指令不影响任何状态标志位
3.11 杂项指令
表36展示了Cortex-M4架构中剩余的指令集:

| 助记符 | 简要说明 | 参见 |
|---|---|---|
| BKPT | 断点 | 第181页BKPT |
| CPSID | 改变处理器状态,禁用中断 | 第182页CPS |
| CPSIE | 改变处理器状态,启用中断 | 第182页CPS |
| DMB | 数据内存屏障 | 第183页DMB |
| DSB | 数据同步屏障 | 第184页DSB |
| ISB | 指令同步屏障 | 第185页ISB |
| MRS | 从特殊寄存器移动到寄存器 | 第186页MRS |
| MSR | 从寄存器移动到特殊寄存器 | 第187页MSR |
| NOP | 空操作 | 第188页NOP |
| SEV | 发送事件 | 第189页SEV |
| SVC | 管理程序调用 | 第190页SVC |
| WFE | 等待事件 | 第191页WFE |
| WFI | 等待中断 | 第192页WFI |
3.11.1 BKPT(断点指令)
断点指令
语法

其中:
-
'imm' 是一个表达式,其求值结果必须是 0-255 范围内的整数(8 位值)。
操作
BKPT 指令会使处理器进入调试状态。调试工具可以利用该指令在特定地址的指令被执行时检查系统状态。
处理器会忽略 imm 的值,但调试器可以将其用于存储与断点相关的附加信息。
BKPT 指令可以放置在 IT 指令块内,但其执行是无条件的,不受 IT 指令所指定条件的影响。
条件标志位
该指令不会改变标志位。
示例

BKPT 0xAB ; 断点指令,立即数值设为 0xAB(调试器可通过程序计数器 PC 定位该指令并提取立即数值)
3.11.2 CPS(修改处理器状态)
处理器状态切换指令
语法

其中:
-
effect 为以下选项之一:
IE:清除特殊功能寄存器
ID:设置特殊功能寄存器 -
iflags 为一个或多个标志位的组合:
i:设置或清除 PRIMASK
f:设置或清除 FAULTMASK
操作
CPS 指令用于修改 PRIMASK 和 FAULTMASK 特殊功能寄存器的值。有关这些寄存器的详细信息,请参阅第23页的"异常屏蔽寄存器"部分。
限制条件
使用该指令时需注意以下限制:
-
仅可在特权级软件中使用,在非特权级软件中执行无效
-
该指令不支持条件执行,因此不得在 IT 指令块中使用
条件标志位
该指令不会改变条件标志位。
示例

CPSID i ; 禁用中断及可配置的故障处理程序(设置 PRIMASK)
CPSID f ; 禁用中断及所有故障处理程序(设置 FAULTMASK)
CPSIE i ; 启用中断及可配置的故障处理程序(清除 PRIMASK)
CPSIE f ; 启用中断及所有故障处理程序(清除 FAULTMASK)
3.11.3 DMB(数据内存屏障)
数据内存屏障指令
语法

其中:
-
cond 为可选条件码(详见第65页"条件执行"说明)
操作
DMB 作为数据内存屏障:
-
确保在程序顺序中位于 DMB 之前的所有显式内存访问操作
-
必须优先于在程序顺序中位于 DMB 之后的所有显式内存访问操作完成
-
不影响非内存访问指令的执行顺序
条件标志位
该指令不会改变条件标志位。
示例

DMB ; 执行数据内存屏障操作
3.11.4 DSB(数据同步屏障)
数据同步屏障指令
语法

其中:
-
cond 为可选条件码(参见第65页"条件执行"章节)
操作
DSB 作为特殊的数据同步内存屏障:
-
确保程序顺序中位于 DSB 之后的所有指令
-
必须等待 DSB 指令执行完毕才能开始执行
-
DSB 指令的完成条件:其之前的所有显式内存访问操作必须全部完成
条件标志位
该指令不会改变任何条件标志位。
示例

DSB ; 执行数据同步屏障操作
3.11.5 ISB(指令同步屏障)
指令同步屏障
语法

其中:
-
cond 为可选条件码(参见第65页"条件执行"章节)
操作
ISB 作为指令同步屏障:
-
清空处理器流水线
-
确保 ISB 之后的所有指令
-
在 ISB 指令完成后重新从缓存或内存中预取
条件标志位
该指令不会改变任何条件标志位。
示例

ISB ; 执行指令同步屏障操作
3.11.6 MRS(从系统寄存器读取到通用寄存器)
将特殊寄存器内容传送至通用寄存器
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Rd:目标寄存器
-
spec_reg:支持以下特殊寄存器:
APSR、IPSR、EPSR、IEPSR、IAPSR、EAPSR、PSR
MSP、PSP、PRIMASK、BASEPRI、BASEPRI_MAX、FAULTMASK、CONTROL
操作说明
-
该指令需与MSR指令配合使用,构成"读取-修改-写入"操作序列
(典型应用场景:清除PSR中的Q标志位,详见第187页MSR指令说明) -
在进程切换代码中:
-
换出进程时:需保存包括PSR内容在内的程序模型状态(使用MRS指令)
-
换入进程时:需恢复程序状态(使用MSR指令)
-
-
注:当与MRS指令配合使用时,BASEPRI_MAX是BASEPRI的别名
使用限制
-
目标寄存器Rd不可为SP(堆栈指针)或PC(程序计数器)
条件标志位
该指令不影响任何条件标志位
应用示例

MRS R0, PRIMASK ; 读取PRIMASK寄存器值并存入R0
3.11.7 MSR(从通用寄存器写入系统寄存器)
将通用寄存器内容传送至特殊寄存器
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
-
Rn:源寄存器
-
spec_reg:支持以下特殊寄存器:
APSR、IPSR、EPSR、IEPSR、IAPSR、EAPSR、PSR
MSP、PSP、PRIMASK、BASEPRI、BASEPRI_MAX、FAULTMASK、CONTROL
操作说明
-
权限控制:
-
非特权级软件仅能访问APSR(参见第21页表5:APSR位定义)
-
特权级软件可访问所有特殊寄存器
-
-
写入规则:
-
非特权级软件对PSR中未分配位或执行状态位的写入将被忽略
-
向BASEPRI_MAX写入时,仅在以下情况会实际写入BASEPRI:
-
Rn 非零且当前BASEPRI值为0
-
Rn 非零且小于当前BASEPRI值
(详见第186页MRS指令说明)
-
-
使用限制
-
源寄存器Rn不可为SP(堆栈指针)或PC(程序计数器)
条件标志位
该指令会根据_Rn_的值显式更新条件标志位
应用示例

MSR CONTROL, R1 ; 读取R1寄存器值并写入CONTROL寄存器
3.11.8 NOP(空操作)
空操作指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
操作特性
-
本指令不执行任何实际操作
-
不保证消耗时钟周期(处理器可能在流水线执行阶段前将其移除)
典型应用
-
代码对齐填充(如使后续指令按64位边界对齐)
条件标志位
该指令不影响任何条件标志位
应用示例

NOP ; 执行空操作
3.11.9 SEV(发送事件)
事件发送指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
操作特性
-
提示性指令(hint instruction)
-
在多处理器系统中向所有处理器发送事件信号
-
同时将本地事件寄存器置1(详见第47页"电源管理"章节)
条件标志位
该指令不影响任何条件标志位
应用示例

SEV ; 发送事件信号
3.11.10 SVC(超级用户调用)
管理程序调用指令
语法

参数说明:
-
cond:可选条件码(参见第65页条件执行章节)
-
imm:8位立即数(取值范围0-255)
操作特性
-
触发SVC异常
-
处理器忽略imm参数值
-
异常处理程序可通过检查该值确定请求的服务类型
条件标志位
该指令不影响任何条件标志位
应用示例

SVC 0x32 ; 管理程序调用(异常处理程序可通过堆栈中的PC值获取立即数)
3.11.11 WFE(等待事件)
事件等待指令(提示性指令)
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
操作逻辑
-
事件寄存器为0时:
-
暂停执行直至以下任一事件发生:
-
未被异常屏蔽寄存器或当前优先级屏蔽的异常
-
当系统控制寄存器SEVONPEND位置1时,进入Pending状态的异常
-
调试功能启用时的调试入口请求
-
多处理器系统中外设或其他处理器通过SEV指令发出的事件信号
-
-
-
事件寄存器为1时:
-
立即将寄存器清零并继续执行
-
(详见第47页"电源管理"章节)
条件标志位
该指令不影响任何条件标志位
应用示例

WFE ; 进入事件等待状态
3.11.12 WFI(等待中断)
中断等待指令
语法

参数说明:
-
cond:可选条件码(参见第65页"条件执行"章节)
操作特性
-
提示性指令(hint instruction)
-
暂停执行直至以下任一事件触发:
-
任意外部中断/异常
-
调试入口请求(无论调试功能是否启用)
-
条件标志位
该指令不影响任何条件标志位
应用示例

WFI ; 进入中断等待状态





















































































































浙公网安备 33010602011771号