ARM处理器CPSR标志位和条件符之间的关系

本文详细解析了ARM处理器中的CPSR状态标志及其与条件码的关系,通过具体的代码示例阐述了如何判断运算结果的正负、零、进位及溢出等情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文目的是要理清ARM处理器的CPSR状态标志和ARM指令的条件符之间的关系。

一、CPSR寄存器

ARM V4的CPSR寄存器(和保存它的SPSR寄存器)中的位分配如下图1所示。

图1 程序状态寄存器格式

状态标志位含义:(其它位的含义和本文主题无关,此处不多介绍)

N
N=1 表示运算的结果为负数;N=0 表示运算的结果为正数或零;
Z
Z=1 表示运算的结果为零;Z=0表示运算的结果为非零;
C
可以有4种方法设置C的值:
─ 加法运算(包括比较指令CMN):当运算结果产生了进位时(无符号数溢出),C=1,否则C=0。
─ 减法运算(包括比较指令CMP):当运算时产生了借位,C=0,否则C=1。
─ 对于包含移位操作的非加/减运算指令,C为移出值的最后一位。
─ 对于其他的非加/减运算指令,C的值通常不改变。
V
可以有2种方法设置V的值:
─ 对于加/减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出。
─ 对于其他的非加/减运算指令,V的值通常不改变

二、条件符及对应的标志位

表1 条件符描述表

三、关于C、V值更多的解释

处理器内部以补码表示有符号数,8个二制位能够表达的整数范围是:+127 ~ -128,16位表达的范围是:+32767 ~ -32768。如果运算结果超出了这个范围,就是产生了溢出,有溢出,说明有符号数的运算结果需要考虑溢出情况。

溢出标志V和进位标志C是两个意义不同的标志。进位标志表示无符号数运算结果是否超出范围;溢出标志表示有符号数运算结果是否超出范围。

处理器对两个操作数进行运算时,按照无符号数求得结果,并相应设置进位标志C;同时,根据是否超出有符号数的范围设置溢出标志V。

应该利用哪个标志,则由程序员来决定。也就是说,如果将参加运算的操作数认为是无符号数,就应该关心进位;认为是有符号数,则要注意是否溢出。

判断运算结果是否溢出有一个简单的规则:只有当两个相同符号数相加,而运算结果的符号与原数据符号相反时,产生溢出;其他情况下,则不会产生溢出。

代码举例1:

LDRr0, =0x7fffffff
LDRr1, =0x70000000;
ADDSr0, r0, r1; //结果=0xefffffff
对于无符号数运算来说,没有进位。
对于有符号数运算来说,溢出。
此时C=0 V=1;

代码举例2:
LDRr0, =0xffffffff
LDRr1, =0x70000000;
ADDSr0, r0, r1; //结果=0x6fffffff
对于无符号数运算来说,有进位。
对于有符号数运算来说,无溢出。
此时C=1 V=0;

代码举例3:
LDRr0, =0x8fffffff
LDRr1, =0xf0000000 ;
ADDSr0, r0, r1; //结果=0x7fffffff
此时C=? V=?;(思考一下,然后在ARM模拟器中验证下)

代码举例4://思考减法时,C值的影响
LDRr0, =0x3
LDRr1, =0x2
SUBSr0, r0, r1
对比:
LDRr0, =0x3
LDRr1, =-2;(-2的补码0xfffffffe会送到r1)
ADDSr0, r0, r1

四、CPSR状态标志和ARM指令的条件符之间的关系

有了上面的背景知识以后,接下来思考表1中CPSR状态标志和ARM指令的条件符之间的关系,下面选取其中的一项来分析。
如:GE:(有符号数大于等于)
N=0 V=0:结果是大于等于0的数,且无符合溢出,所以大于等于关系成立
N=1 V=1:结果小于0,但有符号溢出
考虑以下情况:c=a-b
1.a<0, b<0
减法操作时不可能符号溢出
2.a>0, b<0
可能出现N=V=1?? 如(8位数):100-(-100)=200
显然a>b
3.a<0, b>0
参照上面提到过的判断溢出标志的简单规则,可以得出:在此情况下,
减法操作时如果结果小于0 (N=1),则不会出现符号溢出
所以(在N=1 V=1前提下a<0,b>0)这种情况不可能出现
4.a>0, b>0
减法操作不可能出现符号溢出。

其它项的分析过程类似。

五、总结

尽管以上分析看起来有点复杂,但使用时在大多数情况下用一个简单的条件测试指令即可,不需要程序员计算出条件码的精确值即可得到需要的结果。(作者:刘洪涛,华清远见嵌入式学院讲师。

### ARM处理器中的溢出进位概念及其处理 #### 溢出 (Overflow) 在ARM架构中,溢出通常发生在有号整数运算过程中。当两个带号的操作数相加或相减的结果超出了目标寄存器所能表示的最大范围时就会发生溢出。例如,在32位系统上,如果计算结果超过了\( \pm 2^{31}-1\) 的范围,则会发生溢出。 ARM通过设置程序状态寄存器(CPSR) 中的V标志来指示是否有溢出情况的发生[^3]。一旦检测到溢出,应用程序可以根据需要采取相应措施,比如触发异常或者调整算法逻辑以防止错误传播。 #### 进位 (Carry) 对于无号算术操作以及某些移位指令来说,可能会涉及到进位的概念。进位是指在一个二进制加法或其他类似操作中超出最高有效位的情况;而在减法情况下则是借位不足的情形。 同样地,CPSR内的C标志用于标记是否产生了进位/借位事件。这不仅适用于基本的加减运算,还包括乘除法、比较测试等场景下的条件判断依据之一[^4]。 #### 处理方式 为了应对这些特殊情况,开发者可以在编写汇编代码时利用特定的助记格式指定如何影响或依赖于这两个标志: ```assembly ADD R0, R1, R2 ; 加法不改变任何标志位 ADCS R0, R1, R2 ; 只有条件满足(如之前存在未解决的carry),才会加上额外的一位并更新标志位 ADC R0, R1, R2 ; 总是考虑之前的carry,并据此修改结果及相应的标志位 SUBS R0, R1, R2 ; 减法会根据实际结果自动设定或清除overflow与carry标志 ``` 此外,还可以使用专门针对状态管理设计的一些伪指令来进行更精确控制,像`CMP`(Compare),它可以用来对比两个数值而不做真正的赋值动作,仅更改对应的标志位供后续分支决策使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值