Почему операции MIPS на неподписанных номерах дают подписанные результаты?
Когда я пытаюсь работать с целыми числами без знака в MIPS, результат каждой выполняемой мной операции остается подписанным (то есть все целые числа находятся в дополнении 2), даже если каждая выполняемая мной операция является беззнаковой: addu
, multu
и так четвертый...
Когда я печатаю числа в диапазоне [2^31, 2^32 - 1]
Я получаю их "переполненные" отрицательные значения, как если бы они были подписаны (я думаю, что они есть).
Хотя, когда я пытаюсь что-то вроде этого:
li $v0, 1
li $a0, 2147483648 # or any bigger number
syscall
напечатанный номер всегда 2147483647 (2^31 - 1)
Я в замешательстве... Что мне не хватает?
PS: я не включил свой код, так как он не очень читабелен (например, ассемблерный код), и, если оставить в стороне эту проблему, похоже, работает нормально. Если кто-то считает, что это необходимо, я включу это прямо сейчас!
2 ответа
Из Википедии:
Набор инструкций MIPS32 гласит, что слово unsigned как часть инструкций сложения и вычитания является неправильным. Разница между подписанной и неподписанной версиями команд заключается не в расширении знака (или его отсутствии) операндов, а в том, управляет ли ловушка выполнением при переполнении (например, Add) или переполнение игнорируется (Add unsigned). Непосредственный операнд CONST к этим инструкциям всегда расширяется знаком.
Из справочника инструкции MIPS:
ВСЕ арифметические непосредственные значения имеют расширение знака [...]. Единственное различие между подписанными и неподписанными инструкциями состоит в том, что подписанные инструкции могут генерировать исключение переполнения, а неподписанные инструкции - нет.
Мне кажется, что настоящая проблема - системный вызов, который вы используете для печати чисел. Похоже, и всегда интерпретировать то, что вы передаете как подписанный, и, возможно, также связаны.