条件码---CF和OF
Condition Code---CF and OF
我读了书CS:APP(第三版)和第 3.6.1 节条件代码。它说:
CF: Carry flag. The most recent operation generated a carry out of the most significant bit. Used to detect overflow for unsigned operations.
OF: Overflow flag. The most recent operation caused a two's-complement overflow--either negative or positive.
但我有以下代码。我编译并执行了它。发生了一些不同的事情。
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不包含所有条件?
我的回答假设是 x86。其他架构的行为可能有所不同。
在 x86 上,CF 和 OF 标志都受到有符号和无符号操作的影响(因为 CPU 不知道有符号)。哪些标志相关取决于具体用例。通常,检查 CF 标志是否有无符号算术,而检查 OF 标志是否有符号算术。另见:about assembly CF(Carry) and OF(Overflow) flag
具体解决您的观察:
- CF flag is also set when a borrow from MSB happens. This means, it will be set when subtracting a larger number from a smaller number (like
y1 - x1
), because that requires a borrow from the MSB. See also :
- 同样,OF flag is set whenever the MSB of the result is different from the MSB of both operands of an addition。这意味着,当两个数字加起来大于 MAX_INT(如
x2 + y2
)时,它会被设置,因为结果会设置 MSB。
我读了书CS:APP(第三版)和第 3.6.1 节条件代码。它说:
CF: Carry flag. The most recent operation generated a carry out of the most significant bit. Used to detect overflow for unsigned operations.
OF: Overflow flag. The most recent operation caused a two's-complement overflow--either negative or positive.
但我有以下代码。我编译并执行了它。发生了一些不同的事情。
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。这是怎么发生的?
另外,我还有一张图:
我的回答假设是 x86。其他架构的行为可能有所不同。
在 x86 上,CF 和 OF 标志都受到有符号和无符号操作的影响(因为 CPU 不知道有符号)。哪些标志相关取决于具体用例。通常,检查 CF 标志是否有无符号算术,而检查 OF 标志是否有符号算术。另见:about assembly CF(Carry) and OF(Overflow) flag
具体解决您的观察:
- CF flag is also set when a borrow from MSB happens. This means, it will be set when subtracting a larger number from a smaller number (like
y1 - x1
), because that requires a borrow from the MSB. See also : - 同样,OF flag is set whenever the MSB of the result is different from the MSB of both operands of an addition。这意味着,当两个数字加起来大于 MAX_INT(如
x2 + y2
)时,它会被设置,因为结果会设置 MSB。