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

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

3 ответа

Решение

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

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

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

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

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

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

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

Другие вопросы по тегам