[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