ARM 应用程序状态寄存器APSR的整数状态(NZCV)位

ARM 应用程序状态寄存器APSR的整数状态(NZCV)位

APSR(Application Program Status Register)中的NZCV位 是ARM架构中用于记录运算状态标志的关键位组,位于APSR的第31~28位。它们直接影响条件分支、条件执行等操作。


1. 各标志位含义

标志位 位置 全称 含义
N 31位 Negative(负数) 当运算结果为负数(最高位为1)时置1。
Z 30位 Zero(零) 当运算结果为零时置1。
C 29位 Carry(进位/借位) 无符号运算发生进位(加法)或无借位(减法)时置1。
V 28位 oVerflow(溢出) 有符号运算发生溢出时置1。

2. 如何设置NZCV位?

NZCV位通常由以下指令自动设置:

  • 算术/逻辑运算指令 (若添加 S 后缀):
    ADDS, SUBS, ANDS, LSLS 等。
  • 比较指令 (不保存结果,只更新标志位):
    CMP(相当于 SUBS), CMN(相当于 ADDS), TST(相当于 ANDS)。
  • 其他标志操作指令
    MSR, MRS(直接读写APSR)。

3. 具体触发条件

N(Negative)
  • 置1条件 :运算结果的最高位(bit 31)为1(视为有符号负数)。
  • 示例:
    MOVS R0, #0x80000000 → R0为负数,N=1。
Z(Zero)
  • 置1条件 :运算结果所有位均为0
  • 示例:
    SUBS R0, R1, R1 → R0=0,Z=1。
C(Carry)
  • 加法 :结果产生进位(无符号溢出)时置1。
    ADDS R0, R1, R2 → 若 R1+R2 ≥ 2³²,则 C=1。
  • 减法 :结果无借位 时置1(即被减数≥减数)。
    SUBS R0, R1, R2 → 若 R1 ≥ R2,则 C=1。
  • 移位操作 :C保存最后移出的位
V(oVerflow)
  • 置1条件 :有符号运算结果超出-2³¹ ~ 2³¹-1范围。
  • 判断方法:操作数符号相同且结果符号与操作数相反时置1。
  • 示例(32位有符号数):
    0x70000000 + 0x10000000 = 0x80000000
    → 正数+正数=负数,V=1(溢出)。

4. 典型应用场景

(1) 条件分支(Branch)
armasm 复制代码
CMP R0, R1      ; 计算 R0 - R1,设置NZCV
BGT label       ; 如果 R0 > R1(有符号),跳转到label
  • BGT 的触发条件:Z=0 且 N=V
    (即结果不为零,且负数标志与溢出标志相同)
(2) 条件执行(Conditional Execution)
armasm 复制代码
ADDS R0, R1, R2   ; 加法并设置标志
ADDNE R3, R4, #5  ; 仅当 Z=0(结果非零)时执行
(3) 无符号/有符号比较
  • 无符号比较 :看 CZ
    BHI(无符号大于):C=1且Z=0
    BLS(无符号小于等于):C=0或Z=1
  • 有符号比较 :看 NVZ
    BGT(有符号大于):Z=0且N=V
    BLT(有符号小于):N≠V

5. 常见条件码对照表

条件码 含义 标志位条件 典型场景
EQ 相等 Z=1 CMP后结果为零
NE 不相等 Z=0 结果非零
MI 负数 N=1 结果最高位为1
PL 非负 N=0 结果≥0
VS 溢出 V=1 有符号溢出
VC 无溢出 V=0 无溢出
HI 无符号大于 C=1且Z=0 无符号比较
LS 无符号小于等于 C=0或Z=1 无符号比较
GE 有符号大于等于 N=V 有符号比较
LT 有符号小于 N≠V 有符号比较
GT 有符号大于 Z=0且N=V 有符号比较
LE 有符号小于等于 Z=1或N≠V 有符号比较

6. 注意事项

  • 并非所有指令都更新NZCV(如 MOV 不会),需要显式添加 S 后缀或使用比较指令。
  • Thumb-2指令集 中,大多数16位算术指令总是更新标志位 (除非指定 IT 块条件)。
  • 通过 MRSMSR 指令可以读写APSR,从而手动修改NZCV。

示例代码

armasm 复制代码
    MOVS R0, #10       ; R0=10, 设置NZCV(N=0, Z=0, C=?, V=0)
    SUBS R0, R0, #10   ; R0=0,  Z=1, N=0
    BNE label          ; 不会跳转(因为Z=1,不满足NE条件)
    ADDS R0, R0, #0x7FFFFFFF  ; 触发溢出,V=1

通过理解NZCV,可以深入掌握ARM的条件执行机制,编写高效且可控的底层代码。

相关推荐
底层开发智库8 小时前
无需硬件开发板,从零构建并运行ARM aemfvp-a-rme软件栈
arm开发·arm
HMS工业网络16 小时前
主从结合,安全互联:Anybus工业通信解决方案全栈升级
arm开发
XINVRY-FPGA17 小时前
XC7Z010-2CLG400I Xilinx Zynq-7000 FPGA
arm开发·嵌入式硬件·算法·fpga开发·硬件工程·dsp开发·fpga
浩浩测试一下1 天前
汇编 高低八位寄存器数据存储方式(逆向分析)
汇编·网络安全·逆向·二进制·免杀·寄存器·windows编程
Emtronix英创1 天前
RK3568 CAN驱动测试及使用说明
linux·arm开发·rk3568·全国产主板
时空自由民.3 天前
Arm Coretex-M核MCU做IAP/OTA升级时候为什么要做中断向量表地址偏移?
arm开发·单片机·嵌入式硬件
黑猫学长呀3 天前
存储宝典第1篇:Nand SCA是什么
arm开发·arm·nand·存储芯片·nandflash·onfi
Freak嵌入式3 天前
WIZnet-EVB-Pico2开始,用MicroPython玩转以太网开发
arm开发·人工智能·python·嵌入式硬件·机器人·嵌入式·micropython
振南的单片机世界3 天前
推挽输出:上管推、下管拉,驱动强但不“合群”
arm开发·stm32·单片机·嵌入式硬件
沃普天科技5 天前
USB显示器多屏异显多屏拼接IF8032 IT690 VL171 8801 RTD2556
arm开发·驱动开发·算法·计算机外设·音视频·硬件工程·pcb工艺