Почему для x86 (-64) для подписчиков и без знака умножаются разные инструкции?

Я думал, что весь пункт 2 дополнения состоит в том, что операции могут быть реализованы одинаково для подписанных и беззнаковых чисел. Википедия даже специально перечисляет умножение в качестве одной из операций, которые приносят пользу. Итак, почему у x86 есть отдельные инструкции для каждого, mul и imul? Это все еще верно для x86-64?

Ответ 1

Сложение и вычитание те же, что и нижняя половина умножения. Однако полного размножения нет. Простой пример:

В 32-битном двоичном дополнении -1 имеет то же представление, что и неподписанная величина 2 ** 32 - 1. Однако:

-1 * -1 = +1
(2**32 - 1) * (2**32 - 1) = (2**64 - 2**33 + 1)

(Обратите внимание, что низкие 32 бита обоих результатов одинаковы, и я имею в виду, когда я говорю, что "низкая половина умножения" одинакова).

Ответ 2

Результат будет таким же для версий операндов 2 и 3, за исключением того, что команды mul и imul отличаются тем, как они устанавливают флаги CF и OF (перенос и переполнение).

Подумайте о двух случаях: -1 * -1 против 0xFFFFFFFF * 0xFFFFFFFF в терминах переполнения, и вы получите эту идею.

Ответ 3

Умножение двух 16-битных чисел дает 32-битный результат. Даже если одно из чисел "1", процессор будет эффективно расширять другой до 32 бит. Процесс расширения числа до более длинной длины бит является одной из операций, которая отличается для подписанных и неподписанных значений (другая значимая операция, в которой знака имеет значение, представляет собой сравнение величин, что также является существенной частью деления).