Stockage des valeurs dans les registres HI et LO de MIPS
-
05-07-2019 - |
Question
J'écris certains codes dans MIPS et je suis arrivé au point où l'exigence est de stocker le résultat temporairement dans des registres spéciaux HI
et LO
( les deux font 4 octets de large). Ces instructions sont à ma disposition:
divu s,t lo <-- s div t ; hi <-- s mod t
multu s,t hi / lo < -- s * t ;
Ainsi, divu
enregistre le résultat de la division dans LO
et le reste dans HI
, tandis que multu
enregistre le résultat de multiplication en LO
(4 octets inférieurs) et HI
(4 octets supérieurs).
Plus tard, pour récupérer le résultat des registres HI
et LO
, je peux:
mfhi $v0
mflo $v1
J'ai déjà compris comment stocker le résultat d'un calcul dans LO
:
ori $v0,multu $a0,0x80000000 # Shift $a0 by 32 bits and store into HI/LO
,1 # Store result from $a0 into LO
divu $a0,$v0
- le
divu
stocke le résultat de la division en LO, je divise donc le résultat par 1 pour l’obtenir.
Cependant, stocker dans HI
est plus compliqué. Une solution serait de forcer l’instruction multu
pour décaler la valeur de 32 bits (4 octets):
Mais, le résultat est que la valeur dans HI
est à 1 bit juste de l'endroit où elle devrait se trouver (donc si ma valeur est 0100 1000
, alors HI
contiendra 0010 0100
).
Quelqu'un sait-il comment stocker quelque chose dans le registre HI
?
La solution
Je voudrais prolonger la réponse de Nils Pipenbrinck:
À partir de l’architecture MIPS32 pour les programmeurs
mthi
Format: MIPS32 (MIPS I)
MTHI rs
Objet: Pour copier un GPR dans le registre spécial HI
Description: HI ← rs
Le contenu de GPR rs est chargé dans le registre spécial HI.
Restrictions:
Un résultat calculé écrit dans la paire HI / LO par DIV, DIVU, MULT ou MULTU doit être lu par MFHI ou MFLO. avant qu'un nouveau résultat puisse être écrit en HI ou en LO. Si une instruction MTHI est exécutée après l’une de ces instructions arithmétiques, mais avant un MFLO ou un MFHI instruction, le contenu de LO est IMPRÉVISIBLE. L'exemple suivant montre cette situation illégale:
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
Informations historiques:
Dans MIPS I-III, si l’une des deux instructions précédentes est MFHI, le résultat de cette opération est IMPRÉVISIBLE. Les lectures du registre spécial HI ou LO doivent être séparées de toute instruction ultérieure leur écrivant par deux ou plus d'instructions. Dans MIPS IV et ultérieurs, y compris MIPS32 et MIPS64, cette restriction n’existe pas.
mtlo
Format: MIPS32 (MIPS I)
MTLO rs
Objet: Pour copier un GPR dans le registre des objets spéciaux Description:
LO ← rs
Le contenu de GPR rs est chargé dans le registre spécial LO.
Restrictions: Un résultat calculé écrit dans la paire HI / LO par DIV, DIVU, MULT ou MULTU doit être lu par MFHI ou MFLO avant qu'un nouveau résultat puisse être écrit dans HI ou LO.
Si une instruction MTLO est exécutée après l'une de ces instructions arithmétiques, mais avant une instruction MFLO ou MFHI, le contenu de HI est UNPREDICTABLE. L'exemple suivant montre cette situation illégale:
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
Informations historiques:
Dans MIPS I-III, si l’une des deux instructions précédentes est MFHI, le résultat de cette opération est IMPRÉVISIBLE. Les lectures du registre spécial HI ou LO doivent être séparées de toute instruction ultérieure leur écrivant par deux ou plus d'instructions. Dans MIPS IV et ultérieurs, y compris MIPS32 et MIPS64, cette restriction n’existe pas.
Autres conseils
Le jeu d'instructions MIPS a une contrepartie pour MFLO / MFHI.
Il s’appelle MTLO / MTHI et fait exactement ce que vous voulez:
mtlo $v0 # moves the contents of v0 into the lo-register
mthi $v1 # moves the contents of v1 into the hi-register
Ces instructions sont rares et souvent absentes des références de jeux d'instructions résumées.
Btw: Assurez-vous de consulter le manuel du processeur pour connaître les latences et les dangers liés aux registres LO / HI. Ils sont très spéciaux et votre code peut avoir des choses comme attendre au moins trois cycles entre une écriture et une lecture. Malheureusement, ce comportement dépend du processeur sur lequel vous travaillez.
Se tromper est un piège courant pour les futurs programmeurs MIPS :-)
Pensez aux autres valeurs extrêmes susceptibles de produire des résultats intéressants si vous les utilisez comme deuxième argument de multu / divu (je suis intentionnellement vague parce que cela ressemble à une question de devoir).