Почему в 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 с точки зрения переполнения, и вы поймете идею.