2017-02-01 14 views
1

Перейти на основе сравнения целых чисел, использующих флаг Zero, Sign и Overflow, чтобы определить взаимосвязь между операндами. После CMP с двумя подписанными операндами, есть три возможных сценария-х:Как сравнить флаг Sign and Overflow Flag с отношениями операндов?

  1. ZF = 1 - Destination = Source
  2. SF = OF - Destination> Источник
  3. SF != OF - Destination < Источник

У меня проблемы с пониманием сценариев 2 и 3. Я работал с возможными комбинациями и вижу, что они работают, но я до сих пор не могу понять, почему они работают.

Может ли кто-нибудь объяснить, почему сравнение флагов Sign and Overflow отражает подписанные целочисленные отношения?

Edit:

Там, кажется, некоторое понимание относительно того, что я спрашиваю. В прыжках, основанных на подписанных сравнениях, используются флаг Zero, Sign и Carry - они включают JG, JL и так далее.

Например:

mov al, 1 
cmp al, -1  
jg isGreater 

isGreater: 

Скачок берется из-за переполнения флаг = флаг знака (оба равны 0), что указывает в терминах подписанного сравнения, операнд назначения больше источника.

Если флаг переполнения установлен в 1, а флаг знака установлен в 0, это означает, что назначение меньше.

Мои вопросы - я просто не могу обернуть голову, ПОЧЕМУ это действительно работает.

+4

Подумайте о сравнении как вычитание, когда результат отбрасывается - флаги и их интерпретация имеют больше смысла в этом свете (по крайней мере для меня). –

+1

Из тега [tag: x86] wiki: http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt –

+0

Я понимаю CMP, Carry и Overflow. Я говорю, что не понимаю, как сочетание флага Sign and Overflow отражает взаимосвязь между двумя подписанными операндами, используемыми Jumps на основе подписанных сравнений. – cafekaze

ответ

3

Выполнение подписанного вычитанием R = Destination - Источник дает результат со знаком.

Пусть нет переполнения - обычные арифметические законы справедливо: если R = назначения - Источник> 0, то назначения>Источник.
Не имея переполнения означает OF = 0 и R> 0 означает SF = 0.

Теперь предположим, что переполнение - давайте назовем O самым значительным, не знаком, и бит S знак бит.
условие переполнения означает, что либо а) Вычислив результат-х O требовался заем и результата в S не сделал или б) результат-х O не нужно брать и S сделал.

В случае а), так как в результате S не нужен заем, то два S биты операндов были либо (1, 0) (1, 1) или (0, 0).
Поскольку результат O нуждался в займе и, таким образом, переворачивая первый источник S бит, мы должны исключить второй и третий варианты.
Так операнды знаковые биты были 1 и 0 (таким образом назначения < Источник), результат в знаковый бит SF = 0 и OF = 1 по условию.

В случае б), так как в результате S был нужен заем, то два S биты операндов были (0, 1).
С O не нуждался в заимствовании, первый операнд S бит не был изменен, и нам не нужно рассматривать какой-либо дополнительный случай.
Так операнды знаковые биты были 0 и 1 (таким образом назначения>Источник), результат в знаковый бит SF = 1 и OF = 1 по условию.

Напомним:

  • Если OF = 0 затем Destination>Источник =>SF = 0.
  • Если OF = 1 затем Destination>Источник =>SF = 1.

Короче OF = SF.

3

Флаги OFподписанное переполнение, то есть изменение знака.
Знак знака, очевидно, просто отслеживает, является ли число отрицательным или нет.
Оба флага контролируют знак или самый старший бит (MSB) операнда-адресата.

Сравнительные инструкции CMP выполняют вычитание.
Если A != B и оба операнда имеют один и тот же знак, то очевидно, что следующее произойдет (предположим, что слова dword).

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)). 

Если A и B имеют разные знаки, то следующее произойдет.

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

Это все из возможных сценариев это с OF + SF охватываемого.
Как вы можете видеть A > B только когда SF <> OF и A < B только когда SF = OF.

Единственное исключение - при возникновении неподписанного переполнения.
Предположим, мы сравниваем операнды байтов (-128..127).

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

Однако это вызовет флаг переноса (CF), который нужно установить, что не-переполненные операции не будет.
Эти неправильные результаты возникают только в том случае, если результат вычисления не соответствует размеру операнда, поэтому решение должно внимательно следить за флагом переноса и не предполагать, что OF и SF обрабатывают все возможные случаи.

+0

Это неверно - 'OF' задается посредством XORing выполнения и в MSB и возникает только тогда, когда сумма двух положительных чисел отрицательна или сумма двух отрицательных чисел является положительной (или эквивалентным вычитанием). В 32 битах 100 - 200 не вызовет переполнение. – cafekaze

+0

@cafekaze, пожалуйста, поработайте над своими навыками чтения. Я перечислил предположения о переполнении явно. AS в отношении SF! = MSB, который является семантическим nitpicking. Если вы внимательно прочитаете, вы увидите, что я сказал о нарушениях дорожных знаков. – Johan

+0

@cafekaze, BTW, почему вы говорите о 'SUM'? 'CMP' делает SUBTRACT. – Johan