Я заметил, что unsigned int и int совместно используют одну и ту же инструкцию для сложения и вычитания. Но предоставляет idivl/imull для целочисленного деления и mutiply, divl/mull для unsigned int. Могу ли я узнать причину этого?
Почему X86 обеспечивает пару деления и умножения инструкций?
Ответ 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.