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 ?

Était-ce utile?

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).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top