Sei sulla pagina 1di 6

CHIAMATA A PROCEDURA

Problemi:

 la subroutine contiene parametri formali, è necessario fornire i parametri effettivi di volta in volta
 è necessario allocare dei registri per la restituzione dei risultati
 se non si adottano delle convenzioni potrebbero nascere problemi se il chiamato e il chiamante usino
gli stessi registri

Al termine di una procedura il chiamante si aspetta che i valori dei registri rimangano inalterati, è necessario
riversare i registri in memoria prima di modificarli e ripristinarli al termine della procedura, per minimizzare
le scritture e letture si dividono i registri in due categorie, registri che devono preservati e r. che non devono
essere preservati;

Si adotta la seguente convezione:

 i registri a0-a3 (n° 4-7) sono usati per passare i primi quattro parametri alla procedura, i restanti sono
passati tramite lo stack. Non devono essere preservati.
 i registri vo-v1 (2-3) sono usati per restituire i valori. Non sono preservati.
 i registri s0-s7 (16-23) per valori duraturi, registri che il programma chiamante vuole inalterati dopo
la chiamata e quindi devono essere preservati.
Nel caso la subroutine necessiti di più registri può usare i registri S, salvando i registri che usa prima
di modificarli e ripristinandone il contenuto al termine.
 I registri t0-t7 (n°8 - 15) e t8-t9 (25-25) sono r. temporanei, di libero uso alle procedure, usati per
memorizzare valori temporanei e non devono essere preservati durante una chiamata;
Se il chiamante prevede di usare i registri T dopo la chiamata deve salvarne il valore prima di eseguire
la chiamata.

È conveniente salvare i registri nello stack, grazie alla sua logica LIFO.

Il registro sp è il puntatore allo stack, punta all’ultima parola inserita. Poiché lo stack cresce da indirizzi alti a
indirizzi bassi, in fase di scrittura (push) si decrementa lo sp, si memorizzano i registri, in fase estrazione (pop)
si leggono i valori dallo stack e si incrementa il puntatore.

Per saltare a una procedura si usa l’istruzione di jal X (salta a un dato indirizzo specificato e scrive in $ra
l’indirizzo dell’istruzione successiva a quella di salto).

Se il chiamato chiama a sua volta una procedura deve salvare il registro $ra

Il chiamato restituisce il controllo con un salto indiretto a registro con jr $ra.

VINCOLO ALLINEAMENTO E OEDINAMENTO BYTE


La memoria è vista come un unico grande array unidimensionale. Un indirizzo di memoria costituisce un
indice all’interno dell’array. MIPS utilizza un indirizzamento al byte cioè punta sempre a un byte in memoria.

Byte consecutivi hanno indirizzi consecutivi. L’indirizzo di una word in memoria è sempre multiplo di 4
(requisito detto Vincolo di allineamento). In una word posso essere disposti 4 byte, è l’indirizzo della
parola viene specificato indicando l’indirizzo del primo byte. Il primo byte può essere indirizzato secondo
due modalità:

 Big endian: il byte sono numerati a partire dal byte più significativo, alla parola viene assegnato
l’indirizzo del suo byte più significativo e la memorizzazione/lettura inizia dal byte più sign.
 Little endian
OVERFLOW
Superamento della capacità di rappr. per i numeri in complemento a 2. (I bit a disposizione non sono bastati).

Gestione nel MIPS: Il mips genera un’eccezione, si produce una chiamata a procedura per la gestione
dell’evento non preventivata, ovvero un salto a un indirizzo predefinito. Poiché può verificarsi un overflow
anche all’interno di una subroutine, l’indirizzo dell’istruzione che ha causato l’eccezione è salvato in un
registro detto Exception Program Counter (non sovrascrive il registro $ra), in modo da permettere il ritorno
al programma in cui si è verificato l’overflow. L’istruzione di mfc0 permette di copiare il contenuto di $epc
all’interno dei registri $k0 oppure $k1, poi l’istruzione di jr $k0 permette il ritorno al programma che ha
causato l’overflow. $k0 $k1 (n°26 n°27) sono registri riservati al sistema operativo che non sono ripristinati
durante le eccezioni.

Il mips scatena un eccezione in caso di overflow ma a differenza di altri processori non possiede un’istruzione
di salto condizionato per verificarne l’occorrenza: jp ow. Ma scopre se si è verificato l’overflow con una serie
di istruzioni.

Vantaggi del flag:

 Programmi più leggibili

Svantaggi:

 Ho un’istruzione in più

Filosofia RISC: prevede di implementare nell’hardware solo le operazioni usate più frequentemente

Poiché ho a disposizione 32bit i quali permettono di gestire numeri molto grandi, l’overflow è un evento raro.

PRINCIPI CHE HANNO ISPIRATO IL MIPS


Il mips è un processore RISC. Approccio RISC prevede:

 In hardware vengono implementati solo le operazioni indispensabili, questo permette di avere


prestazioni più efficienti, in quanto l’implementazione di un’altra istruzione penalizza tutte le altre
(aumento del numero delle linee, aumento dei tempi di decodifica, aumento lunghezza delle
istruzioni)
 La scelta delle operazioni implementate è fatta analizzando i programmi più usati (es: compilatori)
al fine di verificare quali istruzioni siano le più frequenti
 un set di istruzione minimale
 poche istruzioni, semplici regolari, rapidamente decodificate e ottimizzate
 solo 5 modi di indirizzamento

FASI DI SVILUPPO DI UN SISTEMA A MICROPROCESSORE


Il progetto di un sistema si divide in sviluppo dell’hardware e sviluppo del software.

Sviluppo hardware:

date le specifiche del progetto:

 progetto del circuito


 realizzazione scheda di prova
 realizzazione di un prototipo
 debug dell’hardware

Sviluppo software:

date le specifiche:

 costruisco un flowchart
 stesura del sorgente dei vari moduli
 sorgente assemblato o compilato
 linker cuce insieme i vari moduli
 debug sw (tramite un simulatore)

Debug si effettua tramite sistemi di collaudo che simula un processore, il test del programma avviene
quindi indipendentemente dall’hardware. L’ambiente di collaudo permette di visionare istruzione per
istruzione l’evoluzione dei registri e della memoria.

Vantaggi simulatore:

 Possibilità di vedere se il programma istruzione per istruzione fa ciò che mi aspetto


 Non è necessario aspettare che l’hardware sia pronto per testare il programma
 Il debug è indipendente dall’hardware

Difetti simulatore:

 Non permette l’iterazione con il mondo esterno in quanto il sistema di sviluppo non ha i sensori
presenti sulla scheda reale.

Il passo successivo è l’integrazione dell’hardware e software. Anche quando hw e sw hanno superato il


debug, è possibile che integrando, il progetto non funzioni. In questo caso si effettua una ricerca degli errori
tramite un Emulatore. L’emulazione consiste nell’estrarre il microprocessore dalla scheda, collegare la
scheda all’ICE (In Circuit Emulator). ICE contiene al suo interno il microprocessore, è dotato di connettori per
connetterlo a un sistema di sviluppo (PC).

Vantaggi emulazione:

 Tramite l’emulazione il software è eseguito sulla scheda reale


 tramite il sistema di sviluppo è possibile vedere l’evoluzione dei registri e della memoria del
processore reale,
 ora è possibile testare l’interazione con il mondo esterno tramite i sensori presenti sulla scheda,
 permette di capire dove siano gli errori tra hw e sw.

Svantaggi emulazione:

 Costo dell’emulatore
 È necessario che la scheda sia pronta

I passi successivi sono:

 Inserire il microprocessore
 Programmare la memoria non volatile
 Costruzione
SYSCALL
 Passaggio parametri tramite $a0-a3 per interi, tramite f0 per virgola mobile
 Codice della chiamata in v0
 Risultati restituiti in v0 e f12

DIRETTIVE PER L’ASSEMBLATORE


Le seguenti direttive permettono di memorizzare costanti o stringhe in memoria (come messagistica),
sottintendono una memoria ROM, il caricamento in memoria è effettuato dall’assemblatore.

ROM perché:

 È necessario mantenere le informazioni in assenza di alimentazione


 Messaggistica e costanti sono definite dal progettista una volta
 Nell’applicazione non è presente l’assemblatore

.ascii “stringa” mette in memoria la stringa, l’assemblatore trasforma la stringa in codice ascii associato a
ogni simbolo e lo carica in memoria

.asciiz “stringa” aggiunge il carattere di terminazione alla fine della stringa

.byte b1…bn memorizza gli n valori in byte consecutivi della memoria

.float e .double f1..fn memorizza gli n valori in singola o doppia precisione, l’assemblatore si occuperà di
calcolare il valore della esponente e della mantissa secondo lo standard

.text le istruzioni successive sono memorizzati nel segmento di testo (indirizzo predefinito
0x400000)

Definisce dove inizia il mio programma

Sottintende la memoria ROM perché si tratta di istruzioni

.data Gli elementi successivi sono memorizzati nel segmento di testo, definisce il punto di inizio
dell’area dati (indirizzo di default 0x1001000)

.space n Alloca n byte nel segmento di testo, serve per riservare un’area di memoria (per
memorizzare i risultati durante l’esecuzione del programma)
Fa riferimento alla memoria RAM perché si tratta di dati da eleborare/produrre durante
l’esecuzione del programma (devono essere scritti, impossibile scrivere nella Read Only)

.globl simb Dichiara l’etichetta simb globale e che ad essa è possibile far riferimento in altri file

.extern simb Dichiara che l’etichetta simb è esterna al file, ovvero è definita globalmente altrove.
L’assemblatore lascia in sospeso questo accoppiamento che sarà risolto dopo il linker
ESTENZIONE DEL SEGNO
Istruzioni che estendono il segno:

 addi addiu
 slti sltiu
 gli offset
 lb lh

Istruzioni che non estendono il segno:

o lbu
o lhu
o ori andi

L’operazione di estensione del segno permette di convertire un numero binario in complemento a due
rappresentato su n bit nel suo equivalente su più di n bit. Dato un numero in c2 positivo, il numero
rappresentato non cambia aggiungendo infiniti 0 davanti, e dato un numero negativo infiniti 1 davanti. Si
rende necessario nel caso del campo immediato delle istruzioni di load, store, branch, add, slt che
contengono un numero su 16 bit in complemento a due (per avere la possibilità di sommare anche numeri
negativi) che deve essere sommato a un registro da 32 bit. Il bit di segno viene copiato nei 16 bit mancanti.

lb considera il byte come un numero con segno e di conseguenza estende il segno

lbu considera il byte come un numero senza segno e non estende il segno (è usato per esempio per caricare
i simboli ASCII).

PRINCIPI
1. Semplicità favorisce regolarità

Esempi sono il fatto che le istruzioni aritmetiche contengono sempre 3 operandi di tipo registro (2 operandi
e un riferimento per il risultato), il cui ordine è fisso. Questo permette di mantenere l’hardware semplice e
permette all’hardware di lavorare sempre nelle stesse condizioni; Stessa dimensione per tutte le istruzioni.

2. Minore sono le dimensioni maggiore è la velocità

Un numero ridotto di registri (32 registri da 32bit) permette di avere un codice operativo di pochi bit di
conseguenza tempi di decodifica minori rispetto ad avere un numero elevato di registri.

3. Un buon progetto richiede buoni compromessi

Esempio: Introduzione di un nuovo formato per le istruzioni (il formato I) il quale permette di specificare un
offset dal 16 bit mantenendo la stessa lunghezza per tutte le istruzioni.

4. Rendere veloce l’evento più frequente

Esempi: Indirizzamento PC relative per i salti condizionati (in cui vi è un’alta probabilità di saltare a locazioni
vicine)

Introduzione di istruzioni come addi per la gestione delle costanti, in quanto gli operandi di tipo
costante sono molto frequenti e il fatto che esse siano specificate nell’istruzione rende la loro esecuzione
più veloce rispetto a caricarle dalla memoria.

La gestione dell’overflow: non è previsto un flag ad hoc per l’overflow perché è un evento raro.