Pregunta

Estoy escribiendo cierto código en MIPS y he llegado al punto donde el requisito es almacenar el resultado, temporalmente, en los registros especiales HI y LO ( ambos tienen 4 bytes de ancho). Estas instrucciones están a mi disposición:

divu     s,t    lo <-- s div t ; hi <-- s mod t
multu    s,t    hi / lo < -- s * t ;

Entonces, divu almacena el resultado de la división en LO y el resto en HI , mientras que multu almacena el resultado de multiplicación en LO (4 bytes inferiores) y HI (4 bytes superiores).

Más tarde, para recuperar el resultado de los registros HI y LO , puedo:

mfhi $v0
mflo $v1

Ya descubrí cómo almacenar el resultado de un cálculo en 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
  • el divu almacena el resultado de la división en LO, así que simplemente divido el resultado entre 1 para obtenerlo allí.

Sin embargo, almacenar en HI es más complicado. Una forma sería forzar la instrucción multu para cambiar el valor en 32 bits (4 bytes):

<*>

Pero, el resultado es que el valor en HI está 1 bit a la derecha de donde debería estar (así que si mi valor es 0100 1000 entonces HI contendrá 0010 0100 ).

¿Alguien sabe cómo almacenar algo en el registro HI ?

¿Fue útil?

Solución

Me gustaría extender la respuesta de Nils Pipenbrinck:

De la arquitectura MIPS32 para programadores

mthi

Formato: MIPS32 (MIPS I)

  MTHI rs

Propósito: Para copiar un GPR al registro HI de propósito especial

Description: HI ← rs

El contenido de GPR rs se carga en el registro especial HI.

Restricciones:

Un resultado calculado escrito en el par HI / LO por DIV, DIVU, MULT o MULTU debe ser leído por MFHI o MFLO antes de que se pueda escribir un nuevo resultado en HI o LO. Si se ejecuta una instrucción MTHI siguiendo una de estas instrucciones aritméticas, pero antes de un MFLO o MFHI instrucción, los contenidos de LO son IMPRIMIBLES. El siguiente ejemplo muestra esta situación 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

Información histórica:

En MIPS I-III, si cualquiera de las dos instrucciones anteriores es MFHI, el resultado de esa MFHI es IMPREDECIBLE. Las lecturas del registro especial HI o LO deben estar separadas de cualquier instrucción posterior que les escriba por dos o más instrucciones En MIPS IV y posterior, incluidos MIPS32 y MIPS64, esta restricción no existe.

mtlo

Formato: MIPS32 (MIPS I)

    MTLO rs

Propósito: Para copiar un GPR al registro LO de propósito especial Descripción:

 LO ← rs

El contenido de GPR rs se carga en el registro especial LO.

Restricciones: MFHI o MFLO debe leer un resultado calculado escrito en el par HI / LO por DIV, DIVU, MULT o MULTU antes de que un nuevo resultado pueda escribirse en HI o LO.

Si una instrucción MTLO se ejecuta siguiendo una de estas instrucciones aritméticas, pero antes de una instrucción MFLO o MFHI, el contenido de HI es IMPREDECIBLE.  El siguiente ejemplo muestra esta situación 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

Información histórica:

En MIPS I-III, si cualquiera de las dos instrucciones anteriores es MFHI, el resultado de esa MFHI es IMPREDECIBLE. Las lecturas del registro especial HI o LO deben estar separadas de cualquier instrucción posterior que les escriba por dos o más instrucciones En MIPS IV y posterior, incluidos MIPS32 y MIPS64, esta restricción no existe.

Otros consejos

El conjunto de instrucciones MIPS tiene una contraparte para MFLO / MFHI.

Se llama MTLO / MTHI y hace exactamente lo que quieres:

  mtlo $v0  # moves the contents of v0 into the lo-register
  mthi $v1  # moves the contents of v1 into the hi-register

Estas instrucciones son raras y a menudo no están presentes en las referencias resumidas del conjunto de instrucciones.

Por cierto: asegúrese de consultar el manual del procesador sobre las latencias y los riesgos relacionados con los registros LO / HI. Son muy especiales y su código puede tener que esperar al menos tres ciclos entre una escritura y una lectura. Lamentablemente, este comportamiento depende de la CPU en la que esté trabajando.

Hacer esto mal es una trampa común para los aspirantes a programadores de MIPS :-)

Piense en qué otros valores extremos podrían producir resultados interesantes cuando se usa como segundo argumento para multu / divu (estoy siendo intencionalmente vago porque esto parece una pregunta de tarea).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top