[M]ade

- Guida Utente -

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

 

i

p

 

 

s

 

 

a

s

m

 

 

 

 

 

 

d

e

b

 

 

u

g

 

 

e

 

 

m

u

l

v

1

.

0

.

2

 

 

 

 

"Reasonable people try to adapt themselves to the world. Unreasonable people try
to adapt the world to the themselves. That's why all progress depends on unreasonable people"
[George Bernard Shaw]

 

 

 


Indice:

1 Introduzione al Made.

1.1 Cos'è il Made?
1.2 Perchè usare il Made?
1.3 Chi ha fatto il Made?
1.4 Per cosa è stato concepito il Made?

2 Installazione del Made.

2.1 Richieste di compilazione
2.2 Compilazione
2.3 Richieste di esecuzione

3 Uso del Made.

3.1 Parametri
3.2 Caratteristiche macchina emulata
3.3 Sintassi Assembler
3.4 Sintassi Debugger


Introduzione al Made

Cos'è il Made?

Il Made (Mips Assembler, Debugger & Emulator) è un programma che facilita la scrittura di programmi in assembly mips. Consiste in un assembler, che si occupa di tradurre il sorgente assembly in un equivalente in linguaggio macchina, di un'emulatore, che permette l'esecuzione del programma su qualsiasi sistema (o quasi...) e di un debugger per l'individuazione e la correzione degli eventuali errori. Il programma è completamente gratuito.

 

Perchè usare il Made?

Il Made è molto utile, in quanto scrivendo a mano (su carta) i programmi in assembly non si può mai avere la certezza che il codice sia corretto. Ciò è soprattutto vero nel caso di opere particolarmente complesse, o per gli utenti alle prime armi. Inoltre avendo un'emulatore, si evitano spiacevoli inconvenienti quali il bloccaggio o il danneggiamento della macchina reale, nel caso si voglia programmare direttamente su un sistema provvisto di una cpu Mips. Benchè esista già un completissimo emulatore Mips gratuito (lo SPIM), questo è molto complesso e ha applicazioni che vanno ben al di là del campo di impiego del Made.

 

Chi ha fatto il Made?

Il Made ad oggi (v1.0.2) è completamente stato concepito, programmato, testato e documentato da Angelo Pesce, studente al primo anno della facoltà di informatica dell'Università degli studi di Salerno. E' stato realizzato sia per comodità personale, sia per l'interesse che questo programma avrebbe potuto destare nella comunità degli studenti, sia come lavoro nell'ambito del corso di Laboratorio di Programmazione I. Chiunque voglia contribuire al Made, espandendolo, modificandolo o semplicemente segnalando errori è pregato di spedire una email a ken@uniserv.uniplan.it o a angpes@zoo.diaedu.unisa.it

 

Per cosa è stato concepito il Made?

Il Made è stato concepito come strumento didattico. L'emulazione non pretende di essere perfetta, in quanto si basa sulle conoscenze dell'autore, senza che sia stata svolta particolare attività di ricerca. Peraltro, alcuni documenti consultati (in particolare l'appendice A del Patterson-Hennessy, riguardante lo Spim e l'encoding delle istruzioni mips) riportano dati errati e/o contrastanti... L'autore non garantisce alcuna compatibilità con il sistema reale. Inolte solo un piccolo sottoset delle istruzioni mips è stato usato, nello specifico non sono emulate tutte le operazioni in virgola mobile e tutte le pseudo-istruzioni oltre che i registri di stato della cpu e gli interrupt. L'emulazione non è cycle-based. Il Made è molto piccolo e veloce, è stato pensato per essere compilato ed eseguito anche su computer di scarsa potenza (386 di fascia bassa), e su terminali solo testo. Per questo il parser è stato scritto da zero in C invece di usare tool come flex e yacc, come ha fatto l'autore dello Spim. Questo rende tutto più snello anche se molto meno robusto. Inoltre il Made genera molti messaggi di errore ed effettua numerosi controlli, così l'uso dovrebbe risultare facilitato. Anche la scelta di usare sempre l'italiano invece dell'inglese non è stata casuale.

 


Installazione del Made

Richieste di compilazione

Il Made è strettamente Ansi C (l'unica eccezione a quanto so è nell'uso dei commenti nel formato //) e non richiede particolari librerie. Si compila su qualsiasi sistema a 32bit, little-endian e con segno in complemento a due. Non è stato provato su sistemi big-endian o con altro sistema di rappresentazione del segno, ma potrebbe funzionare senza modifiche di codice. Se invece si vuole usare un sistema a 16 bit (come il diffuso Borland C/C++ 3) bisogna certamente effettuare delle modifiche al sorgente. Il Made è stato compilato ed eseguito con successo dall'autore con:

DjGpp (Dos, Intel)
Cygwin (Windows, Intel)
VisualC (Windows, Intel)
Gcc (Linux, Intel)
Cc (Digital Unix, Alpha)
Gcc (Digital Unix, Alpha)

 

Compilazione

Per semplicità il Made è contenuto tutto in un solo file sorgente. Quindi il processo di compilazione è banale e non viene fornito un makefile. Esempi:

DjGpp (Dos): gcc -O3 made.c -o made.exe
Watcom C/C++ (Dos): wcl386 -oneatx made.c
Gcc (Linux,Unix): gcc -O3 made.c -o made
Cc (Unix): cc -O2 made.c -o made

 

Richieste di esecuzione

Qualsiasi sistema dotato di schermo, tastiera ed un processore a 32bit :) Questo significa che NON funzionerà sui 286 e gli 8086/88 (a meno di strani miracoli da parte del compilatore).

 


Uso del Made

Parametri

Il primo parametro deve essere il nome del file da assemblare ed eseguire. Può essere seguito da -d per abilitare il debugger.

 

Caratteristiche macchina emulata

La compilazione del codice inizia all'indirizzo 0. La macchina ha 64k di memoria (condivisi per dati e codice) e ha alcuni indirizzi speciali sui quali sono mappati dei registri per l'input/output:

fffb stampa su stdout l'intero inserito
fffc restituisce un'intero da stdin
fffd stampa su stdout il carattere inserito
fffe restituisce un carattere da stdin
ffff esce dal programma

Normalmente lo stdin è la tastiera mentre lo stdout è il monitor. E' possibile effettuare redirezione su file o altro (vedere caratteristiche della shell usata).

 

Sintassi Assembler

L'assembler ha poche funzionalità. Le istruzioni ed i registri vengono notati in maniera classica. Esempio:

sub $1,$1,$4
mult $1,$3
mflo $1

Le costanti possono essere inserite sia come decimali, sia come esadecimali, se prefissate da &. Esempio:

addi $3,$0,4
addi $1,$1,-4
addi $3,$0,&a

Almeno in questa versione non c'e' supporto per le pseudoistruzioni, neppure le comuni move o mult con tre parametri. Sono supportate le label (nella maniera classica) che possono essere usate nelle istruzioni di salto o in quelle di accesso dati, come costanti. Esempio:

lw $2,dati($1)
bne $1,$0,loop

Oltre a questo l'assembler riconosce alcune keyword riservate: .int che inserisce un'intero alla posizione corrente ed incrementa il pc di 4, .byte che inserisce un byte ed incrementa il pc di 1, .regs che inserisce alla posizione corrente un breakpoint di tipo 'ba' (si esegue solo se il Made è stato avviato in modalità debug) .algn ed end che marca la fine del sorgente. 'end' è OBBLIGATORIA e NON FA USCIRE la macchina virtuale. Ciò significa che se usiamo solamente 'end' senza accedere all'indirizzo ffff (esci dal programma) si genererà sicuramente un'errore o il programma entrerà in un ciclo infinito (l'esecuzione infatti continuerà andando in aree di memoria non occupate da reali istruzioni). 'end' infatti è solo una keyword dell'assembler e non si traduce in nessuna istruzione Mips (quindi l'emulatore non può sapere della sua esistenza). '.algn' allinea il codice al margine di 4 byte. Ciò è indispensabile -

 

Sintassi Debugger [Da scrivere]

Il debugger è molto semplice. I comandi sono di due lettere e generalmente non si possono specificare direttamente i parametri anche se sulla maggior sistemi ciò è possibile (dipende dal buffer dello stdin). Ad esempio, usando linux o windows (che sono i due sistemi sul quale ho testato il debugger) è possibile dare il comando:

bm &c1 $1 0 =

che setta un breakpoint alla locazione c1 esadecimale se $1 è uguale a 0. Usare il comando 'ai' per una descrizione dei comandi. Il debugger non è simbolico (le tabelle delle label vengono infatti deallocate dopo l'assemblaggio)

 


Esempio sorgente Made:

# prova [M]ade, by Angelo Pesce
# non esegue alcuna fase di preprocessing, usa un parser molto semplice
# queste linee, prefissate da '#' sono considerate dal parser come commenti ed ignorate


# questo pezzo non serve a nulla, dimostra solo la funzionalità di .algn
j inizio
.byte 3
.algn

inizio:
addi $1,$0,dati # $1=indirizzo inizio dati
addi $2,$0,finedati # $2=indirizzo fine dati
sub $1,$2,$1 # $1=$2-$1 (dimensione dati)
add $3,$0,$0 # pone $3 a zero

loop:
addi $1,$1,-4
lw $2,dati($1) # $2 = valore del dato numero $1
add $3,$2,$3 # $3=$3+$2
bne $1,$0,loop

fine:
.regs # inserisce un breakpoint per permettere la visualizzazione dello stato dei registri
sw $3,&fffb($0) # stampa il risultato
addi $3,$0,&a # '\n'
sw $3,&fffd($0) # stampa '\n'
lw $8,&ffff($0) # fine programma, le costanti esadecimali sono prefissate da '&'


# Area dati...

# dati relativi ad un certo numero di interi
dati:
.int 10
.int 20
.int 30
.int 40
.int 50
finedati:

end # marcatore di fine sorgente