Teoria Progetto MIPS
Il progetto è in linguaggio assembly,che traduce in simboli il linguaggio macchina ed è più vicino a
linguaggio di alto livello. Il set delle istruzioni è di tipo RISC (reduced istruction set control),con architettura
MIPS,maggiormente efficace e pratico del CISC (complex istruction set control).
Questo programma vuole cercare di implementare un algoritmo di ricerca su un vettore (stringa):
inizialmente l’utente inserisce un vettore con 6 valori;poi inserisce un numero,un valore che vuole cercare
all’interno di questo vettore;infine,ci viene detto se il numero sta dentro il vettore o meno e se c’è quante
iterazioni ci sono volute per trovarlo.(e ,in aggiunta,anche quante volte si ripete il numero all’interno della
stringa).
Un programma MIPS ha un struttura standard formata da: .data: che definisce il segmento di dato e che,
dipendentemente dalle variabili dichiarate alloca lo spazio necessario al segmento. Permette di allocare
dati associando un nome: name + directive +initializer;in questo caso abbiamo introdotto:enter ( per il
valore il vettore,stringa da immettere inizialmente),value(per il valore che si vuole cercare all’interno di
questa stringa),found(per affermare che il valore si trova nell’array e vedere quante iterazioni ci sono
volute per trovarlo) not found(per indicare che il valore non è stato trovato),new line e iteration,che ci dice
il numero necessario di iterazioni necessarie per trovare il valore. N.B.: il segmento di dato fa parte
dell’organizzazione della memoria MIPS che contiene anche un segmento di testo che memorizza le
istruzioni del programma,e un segmento di stack di dimensione variabile che si espande verso il basso. Ha
due puntatori £sp(stack pointer) che punta all’ultima parola dello stack , £fp(frame pointer) che punta alla
prima parola del frame e contengono registri salvati e variabili locali;il segmento di dato invece è diviso
in:dati statici,contengono oggetti di dimensione nota al compilatore ,la cui vita è l’intera esecuzione del
programma,e dati dinamici,che possono espandersi verso l’alto per soddisfare le richieste del programma.
.text: definisce il segmento di codice o testo .global: dichiara un elemento come globale,che può essere
riferito anche ad altri files. Main è globale.
Inizialmente il metodo main,definisce le variabili,gli indici di base:il primo introdotto è quello utilizzato per
scorrere gli elementi dell’array(infatti possiamo considerare il vettore un array in quanto quest’ultimo è
una sequenza ordinata di dati),caricando sul registro $t0(che sono registri che utilizzo per memorizzare
valori temporanei) la costante 0 che sarà poi incrementata successivamente per,appunto,consentire la
lettura completa dall’array.In seguito definisco la lunghezza del vettore da considerare(come già,tra
l’altro,ho fatto già in .data) che può essere di massimo 24,caricando nel registro temporaneo $t1 la
costante 24. Sarà incrementato,al fine di cercare il valore nella stringa,anche l’indice del numero trovato;a
questo proposito definisco anche l’indice delle varie iterazioni che mi servono per trovare il valore che
parte stavolta non da 0(come nel caso dei precedenti indici)ma da 1,in quanto questo numero corrisponde
alla posizione 0 del vettore.
La prima cosa da fare è leggere l’array e quindi inserire i numeri che poi lo costituiranno. Per fare ciò
introduco un ciclo for denominandolo “LETTURA”. In MIPS c’è un particolare codice che ci dice che
dobbiamo iniziare scrivendo l’espressione iniziale,una condizione .In questo caso è definita in modo tale
che possiamo inserire massimo 6 numeri che compongono la stringa;quando questa condizione non sarà
più verificata si uscirà dal ciclo per poi andare ad eseguire le restanti istruzioni. Perciò utilizzo l’istruzione
ble(branch if less or equal) di salto condizionato per affermare che: utilizzeremo il successivo metodo
“numero” se $t0 è uguale o minore di $t1.Poichè il primo registro contiene l’indice di scorrimento del
vettore array e il secondo invece la lunghezza massima,allora l’istruzione ci dice che ci sarà un salto al
metodo “numero” se l’indice di scorrimento(denominato i)sarà minore o uguale di 24(lunghezza dell’array).
In seguito ho introdotto dei formati standard,tipici di un linguaggio MIPS,per stampare le stringhe”inserisci
il numero”e “stampa nuova linea”. Per fare ciò è necessario definire in data le stringhe da visualizzare (in
questo casa newline e enter).Poi bisogna caricare in $v0(registri utilizzati per la restituzione di valori)il
codice della chiamata di sistema di una stringa che è 4 e passare poi in $a0(registri invece utilizzati per
passare alle procedure i primi 4 parametri) l’indirizzo della stringa da visualizzare,chiamando infine una
system call(utilizzate per operazioni di input,output;si utilizza quest’espressione per uscire dalla
procedura).Successivamente,chiamo un ulteriore system call per l’inserimento del numero che
costituiranno il vettore(questo è il corpo del ciclo for in MIPS): carico nel registro $v0 la costante 5 che è il
codice per l’inserimento di un numero;poi;come è consuetudine quando si utilizza una procedura ali fine
dell’inserimento di un valore,utilizzo un istruzione move,che sposta il numero prima memorizzato in $v0 in
$a0(solo per convenzione). Memorizzo poi il numero che ho introdotto e che è presente all’interno del
registro $a0, all’interno del vettore che memorizzo nel registro temporaneo $t0. Infine,il ciclo for,come
ogni tipologia di ciclo,richiede un incremento di 4 tramite l’istruzione add(ovviamente incrementa il registro
nel quale è presente il vettore).Poi ho introdotto il salto in condizionato “J lettura” per far si che si ripeta il
ciclo finche non viene soddisfatta la condizione di partenza.
Come già accennato,il successivo metodo è “NUMERO”,nel quale c’è la lettura del numero da cercare e
quindi il suo inserimento all’interno della procedura. Come al solito stampo la stringa che mi serve con
l’usuale schema MIPS e tramite la sycall introduco il codice per l’introduzione del numero,passandolo
poi,sempre per convenzione,in un nuovo registro temporaneo $t2 tramite istruzione move.Infine,con
l’istruzione” li $t0 0”(definito precedentemente nel metodo main come indice scorrimento vettore),resetto
l’indice per consentire di nuovo lo scorrimento da capo dell’array per la lettura del numero inserito.
Poi ho introdotto il metodo “CERCA” per cercare il numero n nel vettore. Essendo anche esso un ciclo
for,devo inizialmente definire una condizione,che una volta non soddisfatta,ci permetterà di uscire dal
ciclo: si passerà al metodo “risultato” se $t0 è minore uguale di $t24,cioè l’ indice di scorrimento deve
essere minore di questo numero. Successivamente,utilizzo un nuovo registro $t3 per inserirci tutti i valori
del vettore,confrontandoli poi con il valore inserito(registro $t2) tramite un istruzione di salto condizionato
beq:se i valori sono uguali,allora si passa al metodo”incrementa”.
“INCREMENTA”:aumenta l’indice di ripetizioni con l’istruzione add $t9 $t9 1,cioè incrementando l’indice
dei numeri trovati definito in data. Poi tramite l’istruzione incondizionata “j” passo a cerca-incrementa
“CERCA –INCREMENTA”:nella quale c’è l’incremento dell’indice di scorrimento del vettore(istruzione add)
per continuare ricerca(incremento indici per scorrere file e leggere),saltando poi di nuovo a cerca. Perciò ho
introdotto una nuova istruzione per trovare il numero delle iterazioni che il programma effettua per
cercare il numero all’interno dell’array: tramite infatti l’istruzione beqz che ci dice che se $t9,cioè se l’indice
dei numero trovati, è uguale a 0,si passa a incrementa-iterazioni. Quindi da questo metodo si può ripassare
o a “cerca” per trovare il numero dopo avere incrementando gli indici per la lettura,o a incrementaiterazioni.
“INCREMENTA-ITERAZIONI”:serve per incrementare l’indice delle iterazioni e per cosi trovare il tanto
atteso valore(incrementando come sempre l’indice scorrimento),effettuando poi un ritorno con il salto
incondizionato a cerca.
Il metodo “RISULTATO” stampa la stringa iteration(il numero delle iterazioni trovate)e fa un salto al
metodo “SI” se l’indice dei numeri trovati è uguale a zero,cioè se si è trovato il numero nell’array,mentre al
metodo “NO” se invece è maggiore di zero allora a “no”.(numero non trovato)
Questi due metodi stampano se hanno trovato o no il numero(tramite stringhe definite in data found e not
found)e nel caso del metodo si stampa anche il numero di ripetizioni del valore nel vettore. Entrambi poi
effettuano un salto al metodo “FINE”,che chiude il progetto con la tipica chiusura con una sycall(codice 10).
Programma infine deve essere eseguito tramite SPIM che è il simulatore per programmi assembly MIPS 32.