Armazenar valores em HI e LO registros de MIPS
-
05-07-2019 - |
Pergunta
Estou escrevendo determinado código em MIPS e eu vim para o ponto onde a exigência é para armazenar o resultado, temporariamente, nos registos HI
e LO
especiais (ambos são 4 bytes de largura). Estas instruções são à minha disposição:
divu s,t lo <-- s div t ; hi <-- s mod t
multu s,t hi / lo < -- s * t ;
Assim, armazena divu
resultar de divisão em LO
e restante em HI
, enquanto armazena multu
resultar de multiplicação em LO
(inferiores 4 bytes) e HI
(superiores 4 bytes).
Mais tarde, para recuperar resultado do HI
e LO
registros, eu posso:
mfhi $v0
mflo $v1
Eu já descobri como armazenar resultado de um cálculo no LO
:
ori $v0,$0,1 # Store result from $a0 into LO
divu $a0,$v0
- as lojas
divu
resultado da divisão em LO, então eu só dividir resultado por 1 a obtê-lo lá.
No entanto, o armazenamento em HI
é mais complicada. Uma forma seria forçar instrução multu
para mudar o valor de 32 bits (4 bytes):
multu $a0,0x80000000 # Shift $a0 by 32 bits and store into HI/LO
Mas, o resultado é que o valor na HI
é 1 bit direito de onde deveria estar (por isso, se o meu valor é 0100 1000
então HI
conterá 0010 0100
).
Alguém sabe como armazenar algo em registo HI
?
Solução
Eu gostaria de estender resposta Nils Pipenbrinck:
De MIPS32 arquitechture para programadores
mthi
Formato: MIPS32 (MIPS I)
MTHI rs
Objetivo: Para copiar um GPR com o registo especial propósito HI
Description: HI ← rs
O conteúdo de GPR rs são carregados em especial HI registo.
Restrições:
Um resultado escrito ao par HI / LO por DIV, Divu, MULT, ou MULTU calculado deve ser lido por MFHI ou MFLO antes de um novo resultado pode ser escrito em qualquer HI ou LO. Se uma instrução MTHI é executado após uma dessas instruções aritméticas, mas antes de um MFLO ou MFHI instrução, o conteúdo de LO são imprevisíveis. O exemplo a seguir mostra essa situação ilegal:
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
Histórico:
MIPS I-III, se qualquer uma das duas instruções anteriores é MFHI, o resultado de que MFHI é imprevisível. Lê da HI ou LO registro especial deve ser separada de quaisquer instruções subsequentes que escrever-lhes por dois ou mais instruções. Em MIPS IV e, mais tarde, incluindo MIPS32 e MIPS64, esta restrição não existe.
mtlo
Formato: MIPS32 (MIPS I)
MTLO rs
Objetivo: Para copiar um GPR para o fim especial LO registo Descrição:
LO ← rs
O conteúdo de GPR rs são carregados no registo especial LO.
Restrições: Um resultado computado escrito ao par HI / LO por DIV, Divu, MULT, ou MULTU deve ser lido por MFHI ou MFLO antes de um novo resultado pode ser escrito em qualquer HI ou LO.
Se uma instrução MTLO é executado após uma dessas instruções aritméticas, mas antes de uma instrução MFLO ou MFHI, o conteúdo do HI são imprevisíveis. O exemplo a seguir mostra essa situação ilegal:
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
Histórico:
MIPS I-III, se qualquer uma das duas instruções anteriores é MFHI, o resultado de que MFHI é imprevisível. Lê da HI ou LO registro especial deve ser separada de quaisquer instruções subsequentes que escrever-lhes por dois ou mais instruções. Em MIPS IV e, mais tarde, incluindo MIPS32 e MIPS64, esta restrição não existe.
Outras dicas
A MIPS instrução de conjunto tem uma contrapartida para MFLO / MFHI.
É chamado MTLO / MTHI e faz exatamente o que você quer:
mtlo $v0 # moves the contents of v0 into the lo-register
mthi $v1 # moves the contents of v1 into the hi-register
Estas instruções são raros e muitas vezes não está presente nas referências resumidas conjunto de instruções.
Btw: Certifique-se de verificar o manual do processador sobre as latências e perigos envolvidos com as regs LO / HI. Eles são muito especiais e seu código pode ter que coisas como esperar pelo menos três ciclos entre uma gravação e uma leitura. Infelizmente este comportamento depende de qual CPU você está trabalhando.
Obter este errado é uma armadilha comum para aspirantes a programadores MIPS :-)
Pense sobre o que outros valores extremos pode produzir resultados interessantes quando usado como o segundo argumento para multu / divu (estou sendo intencionalmente vago, porque esta parece ser uma pergunta lição de casa).