Сохранение значений в регистрах HI и LO MIPS.
-
05-07-2019 - |
Вопрос
Я пишу определенный код в MIPS и дошел до того, что требуется временно сохранить результат в HI
и LO
специальные регистры (оба имеют ширину 4 байта).Эти инструкции в моем распоряжении:
divu s,t lo <-- s div t ; hi <-- s mod t
multu s,t hi / lo < -- s * t ;
Так, divu
сохраняет результат деления в LO
и остаток в HI
, пока multu
сохраняет результат умножения в LO
(нижние 4 байта) и HI
(старшие 4 байта).
Позже, чтобы получить результат из HI
и LO
регистрируется, я могу:
mfhi $v0
mflo $v1
Я уже понял, как сохранить результат расчета в LO
:
ori $v0,$0,1 # Store result from $a0 into LO
divu $a0,$v0
- тот
divu
сохраняет результат деления в LO, поэтому я просто делю результат на 1, чтобы получить его там.
Однако хранение в HI
это сложнее.Одним из способов было бы заставить multu
инструкция для сдвига значения на 32 бита (4 байта):
multu $a0,0x80000000 # Shift $a0 by 32 bits and store into HI/LO
Но в результате значение в HI
на 1 бит правее того места, где должно быть (поэтому, если мое значение равно 0100 1000
затем HI
будет содержать 0010 0100
).
Кто-нибудь знает, как хранить что-либо в HI
регистр?
Решение
Я хотел бы расширить ответ Нильса Пипенбринка:
Из архитектуры MIPS32 для программистов
мти
Формат:МИПС32 (МИПС I)
MTHI rs
Цель:Копирование георадара в регистр HI специального назначения
Description: HI ← rs
Содержимое GPR rs загружается в специальный регистр HI.
Ограничения:
Вычисленный результат, записанный в пару HI/LO DIV, Divu, Mult или MultЕсли инструкция MTHI выполняется в соответствии с одной из этих арифметических инструкций, но перед инструкцией MFLO или MFHI содержимое LO непредсказуемо.Следующий пример демонстрирует эту незаконную ситуацию:
MUL r2,r4 # start operation that will eventually write to HI,LO
... # code not containing mfhi or mflo
MTHI r6
... # code not containing mflo
# this mflo would get an UNPREDICTABLE value
MFLO r3
Историческая информация:
В MIPS I-III, если какая-либо из двух предыдущих инструкций является MFHI, результат этой MFHI НЕПРЕДСКАЗУЕМ.Читает специального регистра HI или LO должен быть отделен от любых последующих инструкций, которые пишут им двумя или более инструкциями.В MIPS IV и более поздних версиях, включая MIPS32 и MIPS64, этого ограничения не существует.
Мтло
Формат:МИПС32 (МИПС I)
MTLO rs
Цель:Чтобы скопировать GPR в специальную цель. Описание регистрации:
LO ← rs
Содержимое GPR rs загружается в специальный регистр LO.
Ограничения:Вычисленный результат, записанный в пару HI/LO с помощью DIV, DIVU, MULT или MULTU, должен быть прочитан MFHI или MFLO, прежде чем новый результат можно будет записать в HI или LO.
Если инструкция MTLO выполняется после одной из этих арифметических инструкций, но до инструкции MFLO или MFHI, содержимое HI будет НЕПРЕДСКАЗУЕМЫМ.Следующий пример демонстрирует эту незаконную ситуацию:
MUL r2,r4 # start operation that will eventually write to HI,LO
... # code not containing mfhi or mflo
MTLO r6
... # code not containing mfhi
# this mfhi would get an UNPREDICTABLE value
MFHI r3
Историческая информация:
В MIPS I-III, если какая-либо из двух предыдущих инструкций является MFHI, результат этой MFHI НЕПРЕДСКАЗУЕМ.Читает специального регистра HI или LO должен быть отделен от любых последующих инструкций, которые пишут им двумя или более инструкциями.В MIPS IV и более поздних версиях, включая MIPS32 и MIPS64, этого ограничения не существует.
Другие советы
Набор инструкций MIPS имеет аналог для MFLO/MFHI.
Он называется MTLO/MTHI и делает именно то, что вы хотите:
mtlo $v0 # moves the contents of v0 into the lo-register
mthi $v1 # moves the contents of v1 into the hi-register
Эти инструкции редки и часто отсутствуют в сводных справочниках по наборам команд.
Кстати:Обязательно ознакомьтесь с руководством процессора о задержках и опасностях, связанных с регистрами LO/HI.Они очень особенные, и вашему коду могут потребоваться такие вещи, как ожидание как минимум трех циклов между записью и чтением.К сожалению, такое поведение зависит от того, над каким процессором вы работаете.
Ошибка — распространенная ошибка для начинающих программистов MIPS :-)
Подумайте, какие еще крайние значения могут дать интересные результаты, если их использовать в качестве второго аргумента для multu/divu (я намеренно расплывчат, потому что это похоже на домашнее задание).