How is Carry Flag set when subtrahend is larger?

痞子三分冷 提交于 2019-12-24 00:15:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!