Сохранение значений в регистрах HI и LO MIPS - PullRequest
4 голосов
/ 05 мая 2009

Я пишу определенный код в 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 реестре?

Ответы [ 3 ]

7 голосов
/ 05 мая 2009

Я бы хотел расширить ответ Нильса Пипенбринка:

Из архива MIPS32 для программистов

mthi

Формат: MIPS32 (MIPS I)

  MTHI rs

Назначение: Для копирования георадара в регистр HI специального назначения

Description: HI ← rs

Содержимое GPR rs загружается в специальный регистр HI.

Ограничения:

Вычисленный результат, записанный в пару HI / LO с помощью DIV, DIVU, MULT или MULTU, должен быть прочитан MFHI или MFLO прежде чем новый результат может быть записан в HI или LO. Если инструкция MTHI выполняется согласно одной из этих арифметических инструкций, но перед MFLO или MFHI инструкция, содержание ЛО НЕПРЕДВИДЕННО. Следующий пример показывает эту недопустимую ситуацию:

 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, это ограничение не существует.

mtlo

Формат: MIPS32 (MIPS I)

    MTLO rs

Назначение: Чтобы скопировать GPR в регистр LO специального назначения Описание:

 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, это ограничение не существует.

6 голосов
/ 05 мая 2009

Набор команд 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 :-)

1 голос
/ 05 мая 2009

Подумайте о том, какие другие экстремальные значения могут привести к интересным результатам, когда они используются в качестве второго аргумента для multu / divu (я намеренно расплывчат, потому что это похоже на вопрос домашнего задания).

...