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

喜你入骨 提交于 2020-11-28 02:19:27

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/41973055/how-does-comparing-the-sign-and-overflow-flag-determine-operand-relationships

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