Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does comparing the Sign and Overflow Flag determine operand relationships?

Jump's based on comparing signed integers use the Zero, Sign, and Overflow flag to determine the relationship between operands. After CMP with two signed operands, there are three possible scenario's:

  1. ZF = 1 - Destination = Source
  2. SF = OF - Destination > Source
  3. SF != OF - Destination < Source

I'm having trouble understanding scenario 2 and 3. I've worked through the possible combinations and see that they do work - but I still can't figure out why they work.

Can anyone explain why a comparison of the Sign and Overflow flags reflects signed integer relationships?

Edit:

There seems to be some understanding regarding what I'm asking. Jumps based on signed comparisons utilize the Zero, Sign, and Carry flag - these include JG, JL, and so on.

For example:

mov   al, 1
cmp   al, -1    
jg    isGreater

isGreater: 

The jump is taken because Overflow flag = Sign Flag (both are 0), indicating in terms of signed comparison, the destination operand is larger than the source.

If the Overflow flag was set to 1 and the Sign flag set to 0, that would indicate the destination is smaller.

My questions is - I just can't seem to wrap my head around WHY this actually works.

like image 425
cafekaze Avatar asked Oct 26 '25 14:10

cafekaze


2 Answers

Performing the signed subtraction R = Destination - Source yields a signed result.

Suppose there is no overflow - the usual arithmetic laws holds: if R = Destination - Source > 0 then Destination > Source.
Having no overflow means OF = 0 and R > 0 means SF = 0.

Now suppose there is an overflow - let's call O the most significant, non-sign, bit and S the sign bit.
An overflow condition means that either a) Computing the result's O needed a borrow and result's S didn't or b) result's O didn't need a borrow and S did.

In case a) since result's S didn't need a borrow, the two S bits of the operands were either (1, 0) (1, 1) or (0, 0).
Since result's O needed a borrow, and thus flipping the first source S bit, we must exclude the second and third option.
So the operands sign bits were 1 and 0 (thus Destination < Source), the result's sign bit SF = 0 and OF = 1 by hypothesis.

In case b) since result's S did need a borrow, the two S bits of the operands were (0, 1).
Since O didn't need a borrow, the first operand S bit has been not changed and we don't need to consider any further case.
So the operands sign bits were 0 and 1 (thus Destination > Source), the result's sign bit SF = 1 and OF = 1 by hypothesis.

To recap:

  • If OF = 0 then Destination > Source => SF = 0.
  • If OF = 1 then Destination > Source => SF = 1.

In short OF = SF.

like image 196
Margaret Bloom Avatar answered Oct 28 '25 02:10

Margaret Bloom


The OF flags tracks signed overflow, i.e. a change in the sign.
The sign flag obviously just tracks whether a number is negative or not.
Both flags monitor the sign or most significant bit (MSB) of the destination operand.

The compare CMP instructions perform a subtract.
If A != B and both operands have the same sign then obviously the following will happen (assume dword operands).

 100 -  200 = -100 (sign change OF=1 + SF=1, ergo A(100) < B(200)).
-100 - -200 =  300 (sign change OF=1 + SF=0, ergo A(-100) > B(-200)).

If A and B have different signs than the following will happen.

-100 - 100 = -200 (no sign change, SF=1, OF=0, A < B)
100 - -100 = 200  (no sign change, SF=0, OF=0, A > B)

That's all possible scenario's with OF+SF covered.
As you can see A > B only when SF <> OF and A < B only when SF = OF.

The only exception is when unsigned overflow occurs.
Let's assume we're comparing byte operands (-128..127).

126 - -126 = -4 (sign change OF=1 + SF=1, ergo A(126) < B(-126)) ***Oops.

However this will trigger the carry flag (CF) to be set, which the non-overflowing operations will not.
These incorrect results only occur when the result of the calculation does not fit inside the operand size, the solution is to keep a close eye on the carry flag and don't assume that OF and SF handle all possible cases.

like image 37
Johan Avatar answered Oct 28 '25 04:10

Johan