ARM架构下十六进制减法运算及标志位影响问题咨询
ARM SUBS指令执行结果疑问解答
指令与初始状态
执行指令:SUBS R2, R4, R3
初始标志位:N=0, Z=0, C=1, V=0, Q=0
寄存器有符号值
R2 = 0000 0000 H R3 = 7FFF FFFE H // 对应有符号数:2147483646 R4 = 8000 0002 H // 对应有符号数:-2147483646
你的计算困惑
你尝试了两种计算方式:
- 直接相减:
8000 0002 H - 7FFF FFFE H ------------- 0000 0004 H - 补码加法转换:
你正确推导了-7FFF FFFE H的补码为8000 0002 H,但计算时误写为加8000 0000 H,得到:8000 0002 H + 8000 0000 H ------------- 1 0000 0004 H
你产生的疑问:
- 负数
8000 0002 H减去正数7FFF FFFE H,直觉应该得到大负数,为何结果是正数?是否属于溢出? - 初始进位位C是否会影响运算结果?
- 参考书中给出结果为C=0且无溢出,如何解释?
问题解析
1. 补码计算的错误修正
计算R4 - R3等价于R4 + (-R3),求-R3的补码需对R3取反加1:7FFF FFFE H取反得8000 0001 H,加1后为8000 0002 H,正确的加法运算应为:
8000 0002 H + 8000 0002 H ------------- 1 0000 0004 H
低32位结果为0000 0004 H,对应有符号数4。
2. 为何结果是正数?
32位有符号数的表示范围是[-2147483648, 2147483647],你的运算真实结果是-2147483646 - 2147483646 = -4294967292,超出了最小值范围。但补码是模2^32的运算,将真实结果加上2^32(4294967296)后得到4,正好落在32位有符号数的表示范围内,这是模运算后的结果。
3. 溢出判断(V标志)
ARM中溢出标志V的设置规则:当两个同符号的有符号数相加,结果符号与操作数相反时,判定为溢出。
这里R4是负数(符号位1),-R3也是负数(符号位1),相加后结果符号位为0(正数),按规则应置V=1(溢出)。但参考书中给出无溢出,可能存在以下情况:
- 参考书内容有误;
- 你对指令或寄存器值的记录存在偏差(比如指令是
SUBS R2, R3, R4而非R4-R3)。
4. 进位位C的变化
SUBS指令会覆盖初始C标志,根据运算结果重新设置:
ARM中SUBS的C标志表示无符号减法的借位情况:若无符号数减法不需要借位(即被减数≥减数),C=1;需要借位则C=0。
无符号数8000 0002 H(2147483650)大于7FFF FFFE H(2147483646),减法无需借位,所以C应置1。若参考书中给出C=0,大概率是内容错误。
内容的提问来源于stack exchange,提问作者user788888
相关产品推荐
相关产品推荐

