进位标志和溢出标志
这次大概总结一下进位标志(Carry Flag, CF)和溢出标志(Overflow Flag, OF)的含义和理解方式
首先明确一点基本认识,处理器本身并不在意也不知道参与算术运算或者逻辑运算的操作数是有符号的还是无符号的。ALU总是为给定的操作数做二进制运算,并根据结果设置相应的标志位。
因此,视参与运算的整数的实际情况,CF或者OF会被独立的置位或者清零。他们的含义是有程序设计者赋予的,在进行无符号运算时,我们需要检查CF来确定运算结果是否正确,而在进行有符号运算时,则通过检查OF来判断结果是否发生溢出。
1. Carry Flag
CF
会在两种情况下变成1:
- 运算结果的最高有效位向更高位进位
- 运算结果的最高有效位从更高位借位
只要在这两种情况以外,CF
总是0。
2. Overflow Flag
OF
会在下面两种情形变为1:
- 两个最高有效位均为0的数相加,得到的结果最高有效位为1
- 两个最高有效位均为1的数相加,得到的结果最高有效位为0
除了这两种情况以外,OF
为0。
使用补码表示有符号数时,最高有效位为0表示正数,最高有效位为1表示负数。因此上面的论述也可以表示为,两个正数相加得到负数,或者两个负数相加得到正数时 OF
置位,否则复位。
对于减法来说也是一样的,正数减去负数得到负数,或者负数减去正数得到正数则 OF
置位,否则均复位。
有符号数溢出总是发生在 0x7f-0x80
这个位置,也就是符号改变的时候。异号的两个数字求和结果位于他们之间,只要操作数本身没有溢出那么结果肯定就不会溢出,因此正数和负数相加不可能导致 OF
置位。
此外,OF
还有另一种理解方式,当次高位向最高有效位的进位值和最高有效位的溢出值不同的时候,OF
为1,否则为0。显然这个规律可以通过亦或运算来表示:$OF=Carray_In \bigoplus Carry_Out $ 。