我阅读了CS:APP(第三版)和第3.6.1节“条件代码”中的书。它说:
CF:进位标志。最近的操作产生了最高有效位的进位。用于检测未签名操作的溢出。
OF:溢出标志。最近的操作导致二进制补码溢出(负数或正数)。
但是我有以下代码。我编译并执行了它。发生了一些不同的事情。
int main() {
char x = 0x66;
char y = 0x39;
char x_bit_not = ~x;
char x_not = !x;
char x_bit_and_y = x & y;
char x_and_y = x && y;
char x_bit_or_y = x | y;
char x_or_y = x || y;
int x1 = (1<<31)-1;
int y1 = 1;
int sum_x1_y1 = x1 + y1;
int diff_x1_y1 = x1 - y1;
int diff_y1_x1 = y1 - x1;
unsigned int x2 = (1<<31)-1;
unsigned int y2 = 1;
unsigned int sum_x2_y2 = x2 + y2;
unsigned int diff_x2_y2 = x2 - y2;
unsigned int diff_y2_x2 = y2 - x2;
}
算术表达式int diff_y1_x1 = y1 - x1;
产生0x80000002
,而没有味精的进位。但是在声明之后,CF等于1。
算术表达式unsigned int sum_x2_y2 = x2 + y2;
甚至不涉及带符号的变体,但是在此语句之后,OF等于1。这是怎么发生的?
我还有另外一张照片: 标题为 CF = Cin XOR Cout 和 OF = Cn XOR Cn-1 。这是什么意思? CS:APP错误吗?还是CS:APP并不包含所有条件?
答案 0 :(得分:2)
我的答案假设为x86。其他架构的行为可能有所不同。
在x86上,CF和OF标志都受带符号和无符号操作的影响(因为CPU不知道带符号的性)。哪些标记是相关的,取决于特定的用例。通常,检查CF标志以查找无符号算术,同时检查OF标志以查找有符号算术。另请参见:about assembly CF(Carry) and OF(Overflow) flag
具体说明您的观察结果:
y1 - x1
)时将设置该位置,因为这需要从MSB借用。另请参阅:Why is the Carry Flag set during a subtraction when zero is the minuend? x2 + y2
)时将被设置,因为结果将设置MSB。