Понимание инструкции Intel SUB - PullRequest
0 голосов
/ 26 января 2020

В настоящее время я пытаюсь углубить свое понимание ассемблерного кода, и несколько недель я застрял с, казалось бы, простой инструкцией:

sub al, BYTE PTR [ebp+4]

Предполагая eax = 0x11223300 и BYTE PTR [ebp+4] = 0xaa каково значение eax после вышеуказанной инструкции?

Насколько я понимаю, al может влиять только на последний байт в eax (0x00 в данном случае), поэтому программа пытается вычислить 0x00 - 0xaa. Но результат будет отрицательным, я не получу, если результат будет просто 0x00 или если числа автоматически преобразуются в отрицательное число, и в этом случае 0xaa само может рассматриваться как отрицательное значение, которое подразумевает, что мы пытаясь вычислить 0x00 - (-0x2a) = 0x2a

Я обнаружил в документации SUB , что

Инструкция SUB выполняет целочисленное вычитание. Он оценивает результат для целых операндов со знаком и без знака и устанавливает флаги OF и CF, чтобы указать переполнение в результате со знаком или без знака, соответственно. Флаг SF указывает на знак подписанного результата.

Но он описывает только некоторое поведение флагов, и я не могу понять, как искать больше о тех, у кого такая спецификация c случай.

Ответы [ 2 ]

3 голосов
/ 26 января 2020

Вы можете думать об этом двумя разными способами, и оба они дают один и тот же результат.

Как без знака, результат вычисляется по модулю 256. Итак 0x00 – 0xaa mod 0x100 = 0x56.

По подписи 0xaa представляет –0x56. (Не –0x2a, как в вопросе.) Итак, 0x00 – (–0x56) = 0x56.

1 голос
/ 26 января 2020

Из того, что я понимаю, al может влиять только на последний байт в eax ...

Это правильно.

Но результат отрицательный ...

Теперь все усложняется.

Как и большинство процессоров, x86 не различает guish между целыми числами без знака и целыми числами со знаком «два дополнения».

Это означает, что 0xaa может означать 170 или (-86), и задача программиста или компилятора интерпретировать значение (если 0xaa означает 170 или -86).

Это возможно, если учитываются только младшие биты вычисления. Пример:

0 + 170   = 0x000000AA
0 + (-86) = 0xFFFFFFAA

или:

0 - 170   = 0xFFFFFF56
0 - (-86) = 0x00000056

В обоих вышеприведенных результатах 8 младших битов равны.

Таким образом, для инструкции, которая будет изменять только младший бит 8 бит, не имеет значения, если 0xaa означает 170 или (-86).

Инструкция SUB x86 запишет младшие 8 битов результата в регистр и "выбросит" верхнюю 24 бита.

ЦПУ устанавливает 4 бита в регистре «флагов» для передачи дополнительной информации об этих 24 битах в программу.

, если результат будет просто 0x00

Некоторые процессоры поддерживают инструкции, которые работают следующим образом: результат вычитания равен 0, если «правильный» результат будет отрицательным.

Однако такие процессоры обычно имеют два разных SUB Инструкция: одна, которая вычисляет как инструкция SUB для x86, а другая инструкция, которая насытит результат до 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...