Domanda

Sto scrivendo un determinato codice in MIPS e sono arrivato al punto in cui l'obbligo è di memorizzare temporaneamente il risultato nei registri speciali HI e LO ( entrambi hanno una larghezza di 4 byte). Queste istruzioni sono a mia disposizione:

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

Quindi, divu memorizza il risultato della divisione in LO e il resto in HI , mentre multu memorizza il risultato di moltiplicazione in LO (4 byte inferiori) e HI (4 byte superiori).

In seguito, per recuperare il risultato dai registri HI e LO , posso:

mfhi $v0
mflo $v1

Ho già capito come memorizzare il risultato di un calcolo in 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
  • divu memorizza il risultato della divisione in LO, quindi divido il risultato per 1 per ottenerlo.

Tuttavia, la memorizzazione in HI è più complicata. Un modo sarebbe forzare l'istruzione multu per spostare il valore di 32 bit (4 byte):

<*>

Ma il risultato è che il valore in HI è 1 bit a destra di dove dovrebbe essere (quindi se il mio valore è 0100 1000 quindi HI conterrà 0010 0100 ).

Qualcuno sa come archiviare qualcosa nel registro HI ?

È stato utile?

Soluzione

Vorrei estendere la risposta di Nils Pipenbrinck:

Da MIPS32 arquitechture per programmatori

MThI

Formato: MIPS32 (MIPS I)

  MTHI rs

Scopo: Per copiare un GPR nello speciale registro HI

Description: HI ← rs

I contenuti di GPR rs vengono caricati nel registro speciale HI.

Restrizioni:

Un risultato calcolato scritto sulla coppia HI / LO da DIV, DIVU, MULT o MULTU deve essere letto da MFHI o MFLO prima che un nuovo risultato possa essere scritto in HI o LO. Se un'istruzione MTHI viene eseguita seguendo una di queste istruzioni aritmetiche, ma prima di un MFLO o MFHI istruzione, il contenuto di LO è INCREDIBILE. L'esempio seguente mostra questa situazione illegale:

 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

Informazioni storiche:

In MIPS I-III, se una delle due istruzioni precedenti è MFHI, il risultato di tale MFHI è IMPREVEDIBILE. Le letture del registro speciale HI o LO devono essere separate dalle istruzioni successive che le scrivono in due o più istruzioni. In MIPS IV e versioni successive, inclusi MIPS32 e MIPS64, questa restrizione non esiste.

mtlo

Formato: MIPS32 (MIPS I)

    MTLO rs

Scopo: Per copiare un GPR nel registro LO per scopi speciali Descrizione:

 LO ← rs

Il contenuto di GPR rs viene caricato nel registro speciale LO.

Restrizioni: Un risultato calcolato scritto sulla coppia HI / LO da DIV, DIVU, MULT o MULTU deve essere letto da MFHI o MFLO prima di poter scrivere un nuovo risultato in HI o LO.

Se un'istruzione MTLO viene eseguita seguendo una di queste istruzioni aritmetiche, ma prima di un'istruzione MFLO o MFHI, il contenuto di HI è INCREDIBILE.  L'esempio seguente mostra questa situazione illegale:

 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

Informazioni storiche:

In MIPS I-III, se una delle due istruzioni precedenti è MFHI, il risultato di tale MFHI è IMPREVEDIBILE. Le letture del registro speciale HI o LO devono essere separate dalle istruzioni successive che le scrivono in due o più istruzioni. In MIPS IV e versioni successive, inclusi MIPS32 e MIPS64, questa restrizione non esiste.

Altri suggerimenti

Il set di istruzioni MIPS ha una controparte per MFLO / MFHI.

Si chiama MTLO / MTHI e fa esattamente quello che vuoi:

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

Queste istruzioni sono rare e spesso non sono presenti nei riferimenti sintetici del set di istruzioni.

Btw: assicurati di controllare il manuale del processore per quanto riguarda le latenze e i rischi associati ai registri LO / HI. Sono molto speciali e il tuo codice potrebbe dover fare cose come aspettare almeno tre cicli tra una scrittura e una lettura. Sfortunatamente questo comportamento dipende dalla CPU su cui stai lavorando.

Sbagliare è una trappola comune per aspiranti programmatori MIPS :-)

Pensa a quali altri valori estremi potrebbero produrre risultati interessanti se usato come secondo argomento di multu / divu (sono intenzionalmente vago perché sembra una domanda a casa).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top