• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

arm的v8r中汇编指令CMN的详细用法

ARMv8-R 架构中的 CMN(Compare Negative)指令用于将一个寄存器中的值与另一个操作数的负值进行比较。它本质上是执行一个加法操作,并根据加法的结果设置当前程序状态寄存器(CPSR 或 APSR)中的条件标志位(Condition Flags),但不会存储加法的结果。这条指令常用于判断一个值是否等于某个特定的负数,或者更直观地进行某些边界检查。

📌 指令格式

CMN 指令的基本语法格式如下:

CMN{<cond>} <Rn>, <operand2>
  • {<cond>}:这是一个可选的条件码后缀。如果使用,指令将在指定条件满足时才执行。例如,CMNEQ R1, R2 表示仅在相等(Equal)条件下执行比较。如果省略,指令将无条件执行。
  • <Rn>:第一个操作数,是存放要进行比值的源数据的寄存器。
  • <operand2>:第二个操作数,可以是一个立即数(Immediate value)或一个寄存器, optionally with shift applied。对于 CMN,指令实际比较的是 Rn 和 -operand2。

⚙️ 操作与标志位

CMN 指令执行的操作可以表示为:
status = Rn + operand2
CMN Rn, Operand2 相当于将寄存器 Rn 的值加上 Operand2 的值,根据加法的结果更新状态寄存器中的条件标志位,但不保存加法结果。

其结果会影响 CPSR(Current Program Status Register)或 APSR(Application Program Status Register)中的以下条件标志位:

标志位 全称 含义 设置条件
N (Negative) Negative 表示结果的符号(最高位) 若结果最高位为1(负数),则置1;否则清0。
Z (Zero) Zero 表示结果是否为零 若结果为0,则置1;否则清0。
C (Carry) Carry 表示加法操作是否发生了无符号溢出(进位) 若加法产生进位(无符号溢出),则置1;否则清0。
V (oVerflow) Overflow 表示加法操作是否发生了有符号溢出 若有符号溢出发生,则置1;否则清0。

需要注意的是:CMN 指令是依据 Rn + operand2 的结果来设置这些标志位的。这些标志位随后可以被后续的条件指令(如 BGT, BLE, BEQ 等)用来控制程序流程。

🖥️ 使用示例

1. 判断寄存器值是否为 -1

CMN  R0, #1          @ 计算 R0 + 1,并根据结果设置标志位
                     @ 如果结果为零(即 R0 + 1 == 0),则 Z 标志置 1
                     @ 这意味着如果 R0 == -1,则 Z=1;否则 Z=0。
BEQ  target_is_neg_one @ 如果 Z 标志为 1(相等),则跳转到 target_is_neg_one

2. 与另一个寄存器的负值进行比较

CMN  R1, R2          @ 计算 R1 + R2,并根据结果设置标志位
                     @ 这相当于比较 R1 和 -R2
BGT  target_if_greater @ 如果 R1 > -R2(从有符号数的角度看),则跳转

3. 检查寄存器值是否小于等于 -100

CMN  R3, #100        @ 计算 R3 + 100,设置标志位
                     @ 如果 R3 <= -100,那么 R3 + 100 <= 0
BLE  target_if_less_or_equal @ 如果结果为负或零(有符号数比较),则跳转

💡 应用场景与注意事项

  • 主要用途:CMN 指令常用于与一个负的立即数进行比较的场景。例如,判断一个值是否等于 -1,使用 CMN R0, #1 比用 CMP R0, #-1 更直观,因为 ARM 汇编中对立即数的取值有一定限制,有时直接使用 CMP 与一个负的立即数可能会遇到立即数合法性问题。
  • 结果不保存:切记 CMN 只修改条件标志位,不保存加法结果到任何寄存器。如果你需要加法的结果,应该使用 ADD 或 ADDS 指令。
  • 条件执行:可以利用条件码 {cond} 让 CMN 指令仅在特定条件下执行,这可以提高代码效率。
  • 与 CMP 的区别:
    • CMP Rn, Operand2 执行的是 Rn - Operand2 。
    • CMN Rn, Operand2 执行的是 Rn + Operand2(即比较 Rn 和 -Operand2)。
    • 例如,CMP R0, #-1 和 CMN R0, #1 想要达到的比较目的是相似的(判断 R0 是否等于 -1),但内部操作不同。

🔍 进一步理解

CMN 指令将寄存器 Rn 中的值加上 operand2 表示的数值,根据加法的结果设置 CPSR 中相应的条件标志位。寄存器 Rn 中的值加上 operand2 的操作结果对 CPSR 中条件标志位的影响,与寄存器 Rn 中的值减去 operand2 的操作结果的相反数对 CPSR 中条件标志位的影响有细微差别。当第二个操作数为 0 或者为 0x80000000 时二者结果不同。例如:

CMP Rn, #0  @ 执行 Rn - 0,若 Rn >= 0 (无符号),通常C(进位)标志置1
CMN Rn, #0  @ 执行 Rn + 0,若 Rn + 0 产生进位(无符号溢出),C标志置1;否则清0。对于非零的Rn,两者的C标志位状态可能不同。

📚 相关指令

  • CMP:比较指令。执行减法操作 (Rn - Operand2) 并设置标志位。
  • TST:测试位指令。执行按位与操作 (Rn & Operand2) 并设置标志位(常用于测试特定位是否为0或1)。
  • TEQ:测试等价指令。执行按位异或操作 (Rn EOR Operand2) 并设置标志位(常用于比较两个值是否相等,且不影响C标志)。

希望这些解释和示例能帮助你更好地理解和使用 ARMv8-R 架构中的 CMN 指令。

posted on 2025-09-19 20:33  SOC验证工程师  阅读(17)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3