I read the book CS:APP(Third Edition) and in Section 3.6.1 Condition Code. It says:
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.
But I have the following code. I compiled and executed it. Something different happened.
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;
}
The arithmatic expression int diff_y1_x1 = y1 - x1;
yeilds 0x80000002
without a carry out from the msg. But after this statement, CF is equal to 1.
The arithmatic expression unsigned int sum_x2_y2 = x2 + y2;
does not even involve signed variants but after this statement, OF is equal to 1. How does this happen?
Also, I have got another picture: And the caption says CF = Cin XOR Cout and OF = Cn XOR Cn-1. What does this mean? Is CS:APP wrong? Or just CS:APP does not contain all the conditions?
My answer assumes x86. Other architectures might behave differently.
On x86, both CF and OF flags are impacted by signed and unsigned operations (because the CPU doesn't know the signed-ness). Which flag(s) are relevant depends on the specific use case. Typically, the CF flag is checked for unsigned arithmetic, while the OF flag is checked for signed arithmetic. See also : about assembly CF(Carry) and OF(Overflow) flag
Addressing your observations specifically :
y1 - x1
), because that requires a borrow from the MSB. See also : Why is the Carry Flag set during a subtraction when zero is the minuend?x2 + y2
), because the result then has the MSB set.User contributions licensed under CC BY-SA 3.0