PDA

Visualizza versione completa : ...qualcuno conosce MIPS?


Lorenzo3
07-08-2008, 10.26.15
Nel caso, vorrei chiedere perché questo programma (di cui posto solo la parte iniziale) mi dà errore quando vado a fare sw $s2, 0($t0), ovvero l'ultima "store" riportata:


.data

#Messaggi per l'inserimento
mess_menu: .asciiz "\n\n1-Inserimento della grammatica\n2-Riconoscimento delle parole\n3-Uscita\nScelta: " # Menu'
mess_ricon: .asciiz "Riconoscimento." # Stub per riconoscimento
mess_iniziale: .asciiz "Inserire simbolo iniziale della grammatica: "
mess_NT: .asciiz "\nInserire prossimo simbolo non terminale: " # Richiesta nuovo non terminale
mess_prod: .asciiz "\nInserire produzione: " # Richiesta nuova produzione

# Messaggi di errore o di correttezza
mess_errore_prod: .asciiz "\n\nErrore: presenza di un non terminale inutile."
mess_errore_vuota: .asciiz "\n\nErrore: grammatica vuota."
mess_ok_check: .asciiz "\n\nLa grammatica inserita è corretta."
mess_no_gramm: .asciiz "\n\nImpossibile effettuare verifica: nessuna grammatica inserita"

# Valori e spazi
Z: .ascii "Z" # Simbolo non terminale fittizio Z
S: .space 1 # Spazio per simbolo iniziale della grammatica
NT: .space 2 # Spazio per nuovo non terminale
prod: .space 3 # Spazio per nuova produzione
coda: .space 2 # Spazio per puntatori inizio e fine coda
parola: .space 21 # Spazio per parola da verificare
M: .space 60 # Spazio per l'insieme M usato dalla procedura "riconoscimento"
N: .space 60 # Spazio per l'insieme N usato dalla procedura "riconoscimento"
.align 2
tabella: .space 12 # Spazio per la jump table
.align 0
.text

###Inserimento

proc_inserimento:
addi $sp, $sp, -16 # Allocazione dello stack
sw $ra, 0($sp) # Ci sono procedure interne, quindi esegue salvataggio
# indirizzo di ritorno

sw $s0, 4($sp) # $s0, $s1, $s2 verranno modificati, quindi salvali
sw $s1, 8($sp)
sw $s2, 12($sp)

move $s0 $zero # $s0 (= Testa) = 0
move $s1 $zero # $s1 (= Coda ) = 0
move $s2 $zero # Registro che conterrà i simboli non terminali correnti

la $a0, mess_iniziale # Stampa richiesta di inserimento del simboli iniziale
li $v0, 4
syscall

li $v0, 12 # Lettura simbolo iniziale, e...
syscall

move $s2, $v0 # ...successivo controllo della correttezza
beq $s2, $zero, errore_vuota

la $t0, S # Salvataggio del simbolo iniziale in opportuno
sw $s2, 0($t0) # spazio in memoria

Lorenzo3
08-08-2008, 15.01.56
Specifico: mi dà errore di non allineamento.

Alucart
09-08-2008, 02.34.06
Non puoi usare SW su indirizzi non multipli di 4, stessa cosa per SH con indirizzi non multipli di 2. Visto che hai attribuito space 1 a S, semplicemente utilizza SB per memorizzare il valore.

Lorenzo3
09-08-2008, 17.33.48
Non puoi usare SW su indirizzi non multipli di 4, stessa cosa per SH con indirizzi non multipli di 2. Visto che hai attribuito space 1 a S, semplicemente utilizza SB per memorizzare il valore.

Infatti io avevo provato a spostare l'istruzione .align 2 che vedi all'inizio.
La cosa buffa è che, sia che io la togliessi sia che la mettessi prima di tutte le allocazioni, mi dava errore di allineamento quando andavo ad allocare la jump table.
Ecco il codice di cui parlo:

la $s0, tabella # Costruzione della jump table per la scelta dal menu'
la $t0, inserimento
sw $t0, 0($s0)
la $t0, riconoscimento
sw $t0, 4($s0)
la $t0, uscita
sw $t0, 8($s0)
j ripeti_menu

Come si spiega?

Alucart
09-08-2008, 18.56.20
Devi usare align 4, non 2. Te l'ho già spiegato, gli indirizzi non multipli di 4 non vanno con SW. Altra cosa: a meno che non sia l'assemblatore a prendersene cura, jump e branch eseguono l'istruzione immediatamente dopo, quindi ci devi per forza mettere qualcosa dopo altrimenti il codice immeditamente successivo verrà eseguito prima del tempo. Esempio:
la $s0, tabella # Costruzione della jump table per la scelta dal menu'
la $t0, inserimento
sw $t0, 0($s0)
la $t0, riconoscimento
sw $t0, 4($s0)
la $t0, uscita
j ripeti_menu
sw $t0, 8($s0)

Lorenzo3
09-08-2008, 19.18.19
Devi usare align 4, non 2. Te l'ho già spiegato, gli indirizzi non multipli di 4 non vanno con SW. Altra cosa: a meno che non sia l'assemblatore a prendersene cura, jump e branch eseguono l'istruzione immediatamente dopo, quindi ci devi per forza mettere qualcosa dopo altrimenti il codice immeditamente successivo verrà eseguito prima del tempo. Esempio:
la $s0, tabella # Costruzione della jump table per la scelta dal menu'
la $t0, inserimento
sw $t0, 0($s0)
la $t0, riconoscimento
sw $t0, 4($s0)
la $t0, uscita
j ripeti_menu
sw $t0, 8($s0)

Eh no, align n significa allinea a 2^n...
Sei sicuro che viene eseguita l'istruzione immedietamente dopo? Anche se il codice non viene eseguito direttamente dalla CPU ma da un emulatore? E se ci mettessi uno spazio bianco...?

Alucart
09-08-2008, 20.36.12
Il valore di align indica byte, non potenze di 2. Metti align 4 e vedrai che il problema dell'allineamento sparirà.
Per il fatto dei salti, sì, sicuro. Mai sentito parlare di lazy jump? È un errore in cui incappano molti alle prime armi con i processori MIPS. Stessa cosa con i delay slot e l'allineamento. Comunque non capisco a che serve uno spazio bianco... Al massimo un nop per compensare, ma se hai un'istruzione prima che può essere eseguita insieme al salto, sposta quella, come nell'esempio che ti ho scritto su.

Lorenzo3
09-08-2008, 20.49.34
.align n

indicates that the items on the succeeding lines should be aligned on a 2^n
byte boundary

Ti ho riportato direttamente dall'Appendice del libro di Laurus...

Il lazy branch ho il dubbio che non ci sia nell'emulatore che usiamo, anche perché non mi ha mai dato fastidio e il professore a che io sappia non ne ha accennato minimamente.

Alucart
09-08-2008, 21.09.32
Con GCC è sempre stato un valore espresso in byte, a meno che le mia versione non sia stata alterata apposta, ma dubito.
Il lazy jump mi sembra strano non ci sia visto che dovrebbe esserci su tutti i MIPS. Evidentemente l'assemblatore che utilizzate lo inserisce automaticamente o l'emulatore è tarocco. :timid:

Lorenzo3
09-08-2008, 21.47.49
E chi ti ha detto che uso GCC? :) Comunque controlla meglio anche tu la tua versione...

Su PCSPIM c'è un'opzione "delayed branch" non settata... magari è quello ;)

Alucart
09-08-2008, 23.08.59
Infatti io non mi riferivo a quello che usi tu, ma a quello che uso io regolarmente. ;) Per il lazy jump, immaginavo ci fosse una direttiva di mezzo, per cui l'emulatore lo simula e il tuo professore non t'ha detto una parola a riguardo. ;D

PS: Ma il programma alla fine lo dà ancora il problema di allineamento usando align 4?

Lorenzo3
09-08-2008, 23.51.30
E daglie con questo align 4 :x: non li allineo i dati a 16 byte!

Per quanto riguarda i problemi con .align 2, vedi sopra.

Alucart
10-08-2008, 02.03.21
Mi sa che hai frainteso la descrizione, come ho fatto anche io leggendo quella riportata poco sopra. Il parametro di align deve essere una potenza di 2, non vuol dire che è generato come una potenza di n^2.
The ALIGN directive is accompanied by a number (X).
This number (X) must be a power of 2. That is 2, 4, 8, 16, and so on... Tra l'altro per allocare la jump table, visto che è statica da quel poco che vedo qui, bastava scrivere:
tabella:
.dw inserimento, riconoscimento, uscitaA meno che non sia fatto apposta l'esercizio.

Lorenzo3
11-08-2008, 01.02.28
Temo con questa storia dell'allineamento di averti definitivamente perso :) .

Alucart
11-08-2008, 01.08.39
Allora mi sa che dovrai rileggerti quello che ho scritto nel mio primo messaggio. ;)

Lorenzo3
11-08-2008, 10.14.31
:D