перенос/переполнение и вычитание в x86
-
12-11-2019 - |
Вопрос
Я пытаюсь разобраться с флагами переполнения и переноса в x86.
Насколько я понимаю, для сложения дополнительных чисел со знаком 2 флаги могут быть сгенерированы только одним из четырех способов (мои примеры - 4-битные числа):
- pos+pos = отрицательный (переполнение)
- 0111 + 0001 = 1000 (7 + 1 = -8)
- pos+neg = pos (перенос)
- 0011 + 1110 = 0001 (3 + -2 = 1)
- neg+neg = отрицание (перенос)
- 1111 + 1111 = 1110 (-1 + -1 = -2)
- neg+neg = pos (переполнение и перенос)
- 1000 + 1001 = 0001 (-8 + -7 = 1)
Итак, в сборке x86 генерирует ли вычитание B из A те же флаги, что и добавление A и -B?
Решение
Вот эталонная таблица, которая может помочь.Это показывает пример возможной комбинации Chently 4 арифметических флага, которые могут возникнуть в результате добавления и подпунктов на x86.«H» ud 'и' d 'Стенд для шестнадцатеричных, без знака десятичных и подписанных десятичных представлений каждого значения.Например, первый ряд для Sub говорит 0xFF - 0xfe= 0x1 без установленных флагов.
Но, я думаю, что короткая история - это то, что ответ Alex является правильным.
. ADD
A B A + B Flags
--------------- ---------------- --------------- -----------------
h | ud | d | h | ud | d | h | ud | d | OF | SF | ZF | CF
---+------+-------+----+------+-------+----+------+-------+----+----+----+---
7F | 127 | 127 | 0 | 0 | 0 | 7F | 127 | 127 | 0 | 0 | 0 | 0
FF | 255 | -1 | 7F | 127 | 127 | 7E | 126 | 126 | 0 | 0 | 0 | 1
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0
FF | 255 | -1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1
FF | 255 | -1 | 0 | 0 | 0 | FF | 255 | -1 | 0 | 1 | 0 | 0
FF | 255 | -1 | FF | 255 | -1 | FE | 254 | -2 | 0 | 1 | 0 | 1
FF | 255 | -1 | 80 | 128 | -128 | 7F | 127 | 127 | 1 | 0 | 0 | 1
80 | 128 | -128 | 80 | 128 | -128 | 0 | 0 | 0 | 1 | 0 | 1 | 1
7F | 127 | 127 | 7F | 127 | 127 | FE | 254 | -2 | 1 | 1 | 0 | 0
SUB
A B A - B Flags
--------------- ---------------- --------------- -----------------
h | ud | d | h | ud | d | h | ud | d || OF | SF | ZF | CF
----+------+-------+----+------+-------+----+------+-------++----+----+----+----
FF | 255 | -1 | FE | 254 | -2 | 1 | 1 | 1 || 0 | 0 | 0 | 0
7E | 126 | 126 | FF | 255 | -1 | 7F | 127 | 127 || 0 | 0 | 0 | 1
FF | 255 | -1 | FF | 255 | -1 | 0 | 0 | 0 || 0 | 0 | 1 | 0
FF | 255 | -1 | 7F | 127 | 127 | 80 | 128 | -128 || 0 | 1 | 0 | 0
FE | 254 | -2 | FF | 255 | -1 | FF | 255 | -1 || 0 | 1 | 0 | 1
FE | 254 | -2 | 7F | 127 | 127 | 7F | 127 | 127 || 1 | 0 | 0 | 0
7F | 127 | 127 | FF | 255 | -1 | 80 | 128 | -128 || 1 | 1 | 0 | 1
Другие советы
При сложении или вычитании возможны все 4 комбинации значений переноса и переполнения.Больше примеров вы можете увидеть в этот ответ.
Этот ответ содержит доказательство того, что керри, который вы получаете от A-B
является обратным переносу, который вы получаете от A+(-B)
.Код по первой ссылке использует это свойство для поворота ADC
в SBB
.
Однако значение подписанного флага переполнения должно быть одинаковым для обоих. A-B
и A+(-B)
потому что это зависит от того, имеет ли результат правильный бит знака, и в обоих случаях бит знака будет одинаковым.