У меня проблемы с пониманием того, что является «правильным» и неправильным при выполнении сложения и вычитания с шестнадцатеричными значениями до подписанного представления. Хочу отметить, что я буду иметь дело с данными размером BYTE.

Например, когда я добавляю 6C (шестнадцатеричный) + 7D (шестнадцатеричный), я получаю ответ E9 (шестнадцатеричный). Теперь, с моей точки зрения, я ЗНАЮ, что E9 является правильным ответом как целое число без знака. 108 (6C) + 125 (7D) = 233 (E9)

Однако моя проблема возникает, когда я пытаюсь определить, правильный ли это ответ в виде подписанного ответа ...

Стоит ли думать о логике ПЕРВОНАЧАЛЬНОГО сложения ?? -

... ИЛИ я должен сказать, что E9 неверен, потому что он вне диапазона [-128, + 127]

.. ИЛИ мне следует взглянуть на это совершенно по-другому, взять 2 дополнения 7D и вычесть это из 6C и посмотреть, подходит ли этот ответ на место, чтобы определить, правильный он или нет?

По сути, мне просто нужно указать в правильном направлении, что искать, чтобы определить, правильна ли подписанная версия ответа или нет. Мне нравятся пошаговые инструкции для таких вещей, но моя книга на ассемблере не слишком помогает.

1
Chase Rutledge 12 Фев 2015 в 01:17

2 ответа

Лучший ответ

Двоичное сложение не имеет понятия, подписано или нет. точно такие же битовые шаблоны. Смысл этих битовых шаблонов - в глазах смотрящего (умножать и делить это не так). В этом красота дополнения двоек.

0xF0 + 0x02 = 0xF2 = 240 + 2 = 242 
0xF0 + 0x02 = 0xF2 = -16 + 2 = -14 

Вычитание, чтобы облегчить вашу жизнь

A - B = A + (-B) = A + (~B) + 1

Теперь знаковое и беззнаковое переполнение по-разному определяется для сложения и вычитания. Итак, получите ли вы «правильный» ответ для подписанных или беззнаковых чисел, зависит от того, есть ли у вас переполнение или нет.

РЕДАКТИРОВАТЬ

6C + 7D = E9 
108 + 125 = 233
108 + 125 != -23

Да, есть подписанное переполнение, если вы обрабатываете их как подписанные числа, тогда вы переполнились, и ответ неверный. Если вы обрабатываете их как беззнаковые числа, у вас не было беззнакового переполнения, ответ правильный.

Беззнаковое переполнение просто выполняется, если результат требует 9 бит 1xx, тогда это беззнаковое переполнение. Для подписанного переполнения, если выполнение следующего за msbit и выполнение из msbit (или другой способ сказать, что это если перенос и перенос msbit не совпадают, тогда это подписанное переполнение). Возможно, вы намеренно выбрали числа, которые упрощают задачу. Мсбит обоих операндов равен 0, перенос - 1, потому что, если бы это были 7-битные числа, которые были бы перенесены. Таким образом, перенос в msbit равен 1, операнды равны 0 и 0 1 + 0 + 0 = 1 с переносом 0, поэтому перенос равен 1, перенос равен 0, переполнение со знаком. Если вы проводите анализ, другой способ проверить подписанное переполнение - если msbit двух операндов одинаковы, а msbit результата не совпадает, тогда это подписанное переполнение.

В основном это та таблица истинности

abi or
000 00
001 01 v
010 01  
011 10
100 01
101 10
110 10 v
111 11

A и b - это msbit операндов, i - перенос, r - результат o - перенос, если i и 0 не совпадают, то это переполнение со знаком. Два случая, когда это происходит, также являются двумя случаями, когда a = b и b! = R

Поэтому ваши два числа, смотрящие на msbits, равны 0 0 1, операнды соответствуют результату, подписанное переполнение, если это подписанное добавление, тогда оно не удалось, вы не можете представить ответ в количестве доступных бит.

2
old_timer 11 Фев 2015 в 23:45

В большинстве языков ассемблера вы проверяете переполнение целочисленных значений со знаком, проверяя флаг переполнения (обычно называемый O или OF или V, в зависимости от архитектуры) в регистре флагов. Каждый раз, когда вы выполняете арифметическую операцию, OF будет установлен, если было целое число со знаком переполнения (если результат не является правильным результатом целого числа со знаком), и сброшен, если переполнения не было.

На x86 флаг называется OF, и вы можете проверить его с помощью инструкции условного перехода (JO для перехода при переполнении или JNO для перехода при отсутствии переполнения), или вы можете использовать INTO для ловушки при переполнении или SETO для установки значение регистра при переполнении.

0
Chris Dodd 12 Фев 2015 в 00:38