Почему X86 обеспечивает пару деления и умножения инструкций?

Я заметил, что unsigned int и int совместно используют одну и ту же инструкцию для сложения и вычитания. Но предоставляет idivl/imull для целочисленного деления и mutiply, divl/mull для unsigned int. Могу ли я узнать причину этого?

Ответ 1

Результаты различаются при умножении или делении, в зависимости от того, подписаны ли ваши аргументы или нет.

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

Например, с 32-битными словами -1 представлен 0xffffffff. В этом случае вы получите разные результаты для подписанных и неподписанных версий:

Signed: -1 * -1 = 1 = 0x00000000 00000001
Unsigned: 0xffffffff * 0xffffffff = 0xfffffffe 00000001

Обратите внимание, что низкое слово результата одинаково. На процессорах, которые не дают вам высоких бит, требуется только одна команда умножения. В PPC есть три команды умножения: одна для младших бит и две для высоких бит в зависимости от того, подписаны ли операнды или нет.

Ответ 2

Большинство микропроцессоров реализуют умножение и деление с помощью алгоритм shift-and-add (или аналогичный алгоритм. курс требует, чтобы знак операндов обрабатывался отдельно.
В то время как реализация умножения и делений с помощью add-an-substract позволила бы не беспокоиться о знаке и, следовательно, позволяла бы взаимозаменяемо использовать знаковые значения без знака без знака, это гораздо менее эффективный алгоритм и, вероятно, почему он не использовался.

Я просто прочитал, что некоторые современные процессоры используют альтернативный метод Бут кодирования, но этот алгоритм также подразумевает утверждение знак значений.

Ответ 3

В знаке x86 хранить в высоком разряде слова (если будет говорить о целых и целых числах без знака) Команды ADD и SUB используют один алгоритм для подписанных и неподписанных в - он получает правильный результат в обоих.

Для MULL и DIV это не сработало. И вы должны "сказать" процессору, что вы хотите "использовать", подписанный или неподписанный. Для беззнакового использования MULL и DIV. Он просто управляет словами - это быстро. Для подписанного использования MULL и IDIV. Он получает слово к абсолютному (положительному) значению, сохраняет знак для результата и затем выполняет операцию. Это медленнее, чем MULL и DIV.