问题
I know the Carry flag during SUB
is set whenever the minuend is smaller than the subtrahend and a borrow is required, but haven't been able to find anything explaining this in more detail.
Since subtraction is actually just adding with two's complement, how does the CPU know that the subtrahend is larger and a borrow has occurred?
The only thing I can think of is that maybe the Carry flag is set automatically during SUB
, whenever converting the subtrahend to its 2's complement. Then unless another Carry occurs (as it should during the addition whenever the minuend is larger than the subtrahend) to switch it back off, it stays on.
Or am I way off?
回答1:
You seem to confuse the carry and overflow flags.
The carry flag checks unsigned overflow and the overflow flag checks signed overflow.
The way this works is that prior to subtraction the (unsigned) numbers are compared and if b > a then CF is set.
If the sign of the first operand changes overflow is set.
During the subtraction the CPU does not care whether the operands are negative.
If the unsigned base is smaller than the unsigned number being subtracted then a carry occurs.
E.g. (just tested in the CPU view of my debugger)
0 - -1 = 1 ->> CF = 1, because 0xFFFFFFFF > 0
10 - -1 = 11 ->> CF = 1, same reason
-2 - 4 = -6 ->> CF = 0, because 0x4 < 0xFFFFFFFE
Remember in signed arithmetic these results are correct, but in unsigned arithmetic they are *way* off, hence CF=1.
The carry flag does not know or care about sign, it is (only) meant for unsigned overflow. Remember the CPU has no way of knowing whether you want to perform signed or unsigned operations. It is up to the application to test the relevant flags to interpret the results, this is why the CPU provides two sets of overflow flags.
Here's a list of the most common flags and their function:
code | descripton |name | When set
---+++----------------+---------+-------------------
CF unsigned overflow Carry If unsigned over-/underflow occurs
OF signed overflow Overflow If sign bit (MSB) flips
SF Sign flag Sign If MSB is set, i.e. is result is negative
ZF Zero flag Zero If Result is zero
Neither of these flags have much in the way of 'intelligence'.
You need to remember that these flags were designed when transistors where in short supply.
About 2's complement
2's complement is designed so that addition and subtraction don't need to know about the conversion from positive to negative.
You can just add and subtract without care if the operand or the result will be positive or negative.
The only caveats occur on overflow, which is exactly what the carry flag tests.
If you where to use plain inversion (i.e. 1's complement) as negative numbers then you'd need all sorts of safeguards around addition and subtraction; this is why 2's complement is universally used.
Further reading
http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt
Thanks Peter
来源:https://stackoverflow.com/questions/41841768/how-is-carry-flag-set-when-subtrahend-is-larger