© 2002-2003 Riccardo Solmi 1
TITLE
Assembler MIPS R2000/3000 Progetto
Riccardo Solmi
2
Introduzione
§ Scopo del progetto
• Utilizzare l’assembly MIPS per realizzare un programma complesso
• Prendere confidenza con l’architettura degli elaboratori scrivendo un programma di emulazione di un altro processore
§ Processore scelto: JVM
• La Machina Virtuale Java (JVM) è una macchina astratta.
• Ha un set di istruzioni (bytecode)
• Usa diverse aree di memoria
• La JVM può essere implementata in hardware oppure più comunemente in software con un interprete o compilatore.
• Viene usata per eseguire i programmi Java e anche per altri linguaggi
• I programmi per la JVM sono portabili
© 2002-2003 Riccardo Solmi 3
Bibliografia
§ The Java Virtual Machine Specification
• Manuale ufficiale della Macchina Virtuale Java http://java.sun.com/docs/books/vmspec/2nd- edition/html/VMSpecTOC.doc.html
• Il capitolo 6 descrive il set di istruzioni della JVM
§ Jasmin assembler
• E’ un assembler per programmare la JVM http://mrl.nyu.edu/~meyer/jvm/jasmin.html
§ Trovate tutto nella pagina web relativa a questo modulo:
• http://www.cs.unibo.it/~solmi/teaching/arch_2002-2003.html
4
Restrizioni adottate per la nostra JVM
§ Niente operazioni orientate agli oggetti (OO)
• Niente creazione di oggetti
• Niente accesso ai campi degli oggetti
• Niente invocazione di metodi su oggetti
§ Un solo frame di attivazione
• Perché nella JVM esistono solo chiamate a funzione OO.
§ Solo istruzioni su interi a 32bit con segno
• Niente byte, short, long, char, float e double
• Niente istruzioni di conversione da un tipo ad un altro
© 2002-2003 Riccardo Solmi 5
Descrizione della nostra JVM
§ L’area codice
• Dove viene memorizzato il programma
§ Il registro pc (program counter)
• Contiene l’indirizzo dell’istruzione da eseguire
• All’inizio il pc punta all’inizio dell’area codice
6
Descrizione della nostra JVM
§ JVM frame
• Contiene le variabili locali e lo stack degli operandi
§ Variabili locali
• Un array (sequenza) di variabili intere indirizzabili con la posizione
§ Stack degli operandi
• Le istruzioni estraggono i parametri dallo stack degli operandi e vi inseriscono il risultato
• Lo stack degli operandi sostituisce i registri
• Gli slot dello Stack sono tutti a 32 bit
© 2002-2003 Riccardo Solmi 7
Tipi di Istruzioni
§ Istruzioni di caricamento e salvataggio
• Trasferiscono i dati tra lo stack degli operandi e le variabili locali
• Oppure, caricano nello Stack una costante
§ Istruzioni aritmetiche
• Estraggono gli operandi dallo stack, eseguono una operazione aritmetica e mettono il risultato nello Stack
§ Gestione Stack degli operandi
• Per duplicare, scambiare ed estrarre dati dallo Stack
§ Istruzioni di salto
• Per trasferire il controllo in un altro punto del codice
• Si dividono in salti condizionati e salti incondizionati
8
Formato delle istruzioni
§ Formato istruzioni
• Istruzioni senza operandi (1 byte)
• Istruzioni con un operando (2 byte)
• Istruzioni con due operandi (3 byte)
§ NB per comodità al posto dell’opcode uso il mnemonico Opcode
Opcode Operando
Opcode Operando1 Operando2
© 2002-2003 Riccardo Solmi 9
§ Operazione
• iload – Carica un intero da una variabile locale
• istore – Salva un intero in una variabile locale
• iload_0, iload_1, iload_2, iload_3 – Carica un intero da una delle prime 4 variabili locali
• istore_0, istore_1, istore_2, istore_3 – Salva un intero in una delle prime 4 variabili locali
• aload – Carica un indirizzo da una variabile locale
• astore – Salva un indirizzo in una variabile locale
• aload_0, aload_1, aload_2, aload_3 – Carica un indirizzo da una delle prime 4 variabili locali
• astore_0, astore_1, astore_2, astore_3 – Salva un indirizzo in una delle prime 4 variabili locali
• bipush, sipush – Carica rispettivamente una costante a 8 o 16 bit con segno
• iconst_m1, iconst_0, iconst_1, iconst_2, iconst_3, iconst_4, iconst_5 – Carica una costante rispettivamente uguale a: -1, 0, 1, 2, 3, 4, 5
§ NB i dati vengono caricati e salvati nello Stack operandi
Istruzioni di caricamento e salvataggio
10
§ Operazione
• iload – Carica un intero da una variabile locale
§ Formato Stack
§ Descrizione
• Legge il valore della variabile locale index e lo inserisce nello Stack
Istruzioni di caricamento e salvataggio: iload
sp pc
iload
index sp val
… …
lv
index val
© 2002-2003 Riccardo Solmi 11
§ Operazione
• istore – Salva un intero in una variabile locale
§ Formato Stack
§ Descrizione
• Estrae dallo Stack un valore e lo salva nella variabile locale index.
Istruzioni di caricamento e salvataggio: istore
sp pc
istore
index sp val
…
…
lv
index val
12
§ Operazione
• iload_2 – Carica un intero dalla variabile locale 2
§ Formato Stack
§ Descrizione
• Legge il valore della variabile locale 2 e lo inserisce nello Stack.
Istruzioni di caricamento e salvataggio: iload_2
sp pc
iload_2
sp val
… …
lv
2 val
© 2002-2003 Riccardo Solmi 13
§ Operazione
• istore _1 – Salva un intero nella variabile locale 1
§ Formato Stack
§ Descrizione
• Estrae dallo Stack un valore e lo salva nella variabile locale 1 Istruzioni di caricamento e salvataggio: istore_1
sp
sp val
…
…
lv 1 val pc
istore_1
14
§ Operazione
• sipush – Carica nello Stack una costante 16bit con segno
§ Formato Stack
§ Descrizione
• Inserisce nello Stack un valore ottenuto estendendo il segno alla costante con segno così ottenuta:
• (byte1 << 8) | byte2
• Dove: << shift e | or
Istruzioni di caricamento e salvataggio: sipush
pc
sipush
sp value
sp … …
byte1 byte2
© 2002-2003 Riccardo Solmi 15
§ Operazione
• iconst_3 – Carica nello Stack la costante intera 3
§ Formato Stack
§ Descrizione
• Inserisce nello Stack la costante intera 3
Istruzioni di caricamento e salvataggio: iconst_3
pc
iconst_3
sp 3
sp … …
16
§ Operazione
• iadd – Somma due interi
• isub – Sottrae due interi
• imul – Moltiplica due interi
• idiv – Quoziente della divisione di due interi
• irem – Resto della divisione di due interi
• ineg – Cambio di segno di un intero
• ishl – Shift a sinistra di s bits
• ishr, iushr – Shift a destra di s bits con o senza segno
• ior – Or tra due interi
• iand – And tra due interi
• ixor – Or esclusivo tra due interi Istruzioni aritmetiche
© 2002-2003 Riccardo Solmi 17
§ Operazione
• iadd – Somma due interi
§ Formato Stack
§ Descrizione
• Estrae dallo Stack due valori interi, li somma e inserisce nello Stack il risultato
Istruzioni aritmetiche: iadd
pc
iadd
sp
val1
…
sp result
…
val2
18
§ Operazione
• pop – Estrae una word dallo Stack
• pop2 – Estrae due word dallo Stack
• dup – Stack: …,word ? …,word,word
• dup2 – Stack: …,w2,w1 ? …,w2,w1,w2,w1
• dup_x1 – Stack: …,w2,w1 ? …,w1,w2,w1
• dup2_x1 – Stack: …,w3,w2,w1 ? …,w2,w1,w3,w2,w1
• dup_x2 – Stack: …,w3,w2,w1 ? …,w1,w3,w2,w1
• dup2_x2 – Stack: ...,w4,w3,w2,w1 ? …,w2,w1,w4,w3,w2,w1
• swap – Scambia le due word in cima allo Stack
§ NB una word può essere un intero o un indirizzo Istruzioni di gestione dello Stack operandi
© 2002-2003 Riccardo Solmi 19
§ Operazione
• pop2 – Estrae due word dallo Stack
§ Formato Stack
§ Descrizione
• Estrae dallo Stack due word (possono essere interi o indirizzi)
• Le due word estratte vengono “buttate via”
Istruzioni di gestione dello Stack operandi: pop2
pc
pop2
sp
word2
… sp …
word1
20
§ Operazione
• dup_x1 – Duplica la cima dello Stack e lo mette 2 word sotto
§ Formato Stack
§ Descrizione
• Riarrangia la cima dello Stack come da figura
Istruzioni di gestione dello Stack operandi: dup_x1
pc
dup_x1
sp
word2
…
word1
sp
word2
…
word1 word1
© 2002-2003 Riccardo Solmi 21
§ Operazione
• swap – Scambia le due word in cima dello Stack
§ Formato Stack
§ Descrizione
• Riarrangia la cima dello Stack come da figura
Istruzioni di gestione dello Stack operandi: swap
pc
swap
sp
word2
…
word1
sp
word1
…
word2
22
§ Operazione (salto condizionato)
• ifeq, ifne – Salta se il valore è uguale o diverso da zero
• iflt, ifle – Salta se il valore è minore di o minore uguale a zero
• ifgt, ifge – Salta se il valore è maggiore di o maggiore uguale a zero
• if_icmpeq, if_icmpne – Salta se i valori sono uguali o diversi
• if_icmplt, if_icmple – Salta se il primo valore è < o <= al secondo
• if_icmpgt, if_icmpge – Salta se il primo valore è > o >= al secondo
• if_acmpeq, if_acmpne – Salta se gli indirizzi sono uguali o diversi
§ Operazione (salto incondizionato)
• goto – Salta ad un indirizzo
• jsr – Salta ad un indirizzo e salva il valore di ritorno (nello Stack)
• ret – Salta all’indirizzo contenuto in una variabile locale
§ NB Il valore/i valori da confrontare vengono estratti dallo Stack
§ NB L’indirizzo di destinazione è rappresentato da un offset a 16 bit.
Istruzioni di salto
© 2002-2003 Riccardo Solmi 23
§ Operazione
• ifeq – Salta se il valore è uguale a zero
§ Formato Stack
§ Descrizione
• Estrae un valore dallo Stack e se val = 0 salta all’indirizzo ottenuto sommando a quello corrente (pc) un offset con segno così calcolato:
• (byte1 << 8) | byte2 Istruzioni di salto: ifeq
pc
ifeq
sp val
… sp …
byte1 byte2
24
§ Operazione
• if_icmplt – Salta se il primo valore è minore del secondo
§ Formato Stack
§ Descrizione
• Estrae due valori dallo Stack e se val1 < val2 salta
all’indirizzo ottenuto sommando a quello corrente (pc) un offset con segno così calcolato:
• (byte1 << 8) | byte2 Istruzioni di salto: if_icmplt
pc
if_icmplt
sp
val1
…
sp …
val2 byte1
byte2
© 2002-2003 Riccardo Solmi 25
§ Operazione
• goto – Salta ad un indirizzo
§ Formato
§ Descrizione
• Salta all’indirizzo ottenuto sommando a quello corrente (pc) un offset con segno così calcolato:
• (byte1 << 8) | byte2 Istruzioni di salto: goto
pc
goto byte1 byte2
26
§ Operazione
• jsr – Salta ad una subroutine
§ Formato Stack
§ Descrizione
• Salta all’indirizzo ottenuto sommando a quello corrente (pc) un offset con segno così calcolato:
• (byte1 << 8) | byte2
• L’indirizzo dell’istruzione successiva viene messo nello Stack
Istruzioni di salto: jsr
pc
jsr
sp addr
sp … …
byte1 byte2 addr
© 2002-2003 Riccardo Solmi 27
§ Operazione
• ret – Salta ad un indirizzo contenuto in una variabile locale
§ Formato
§ Descrizione
• Legge l’indirizzo contenuto nella variabile locale index e vi salta
Istruzioni di salto: ret
pc
ret index
lv
index addr
28
Precisazioni
§ Esiste anche una istruzione nop che non fa nulla
§ Quando termina la simulazione?
• In un vero processore... mai
• Nel nostro emulatore:
• Quando viene trovata un’istruzione non emulata
• Nella tabella che segue viene usato l’identificatore err
§ Come si fa a capire se il simulatore funziona correttamente?
• Si scrivono dei programmi di test
• I test possono essere pubblicati sul newsgroup
© 2002-2003 Riccardo Solmi 29
Esempio di programma
.data
bytecode: .byte 2 # iconst_m1 .byte 16,15 # bipush 15 .byte 5 # iconst_2 .byte 104 # imul .byte 96 # iadd .byte 59 # istore_0 .byte 255 # err
30
Sorgente fornito assieme al progetto
.data .align 4
.word 0xffffffff,0xffffffff,0xffffffff,0xffffffff localVars: .space 64 # 16 local variables
.space 64 # 16 operand slots operandStack:
.align 4
.word 0xffffffff,0xffffffff,0xffffffff,0xffffffff opcodeTable: .word _nop, err, iconst_m1, iconst_0, iconst_1,
# ...
© 2002-2003 Riccardo Solmi 31
Consegna
§ Un mail con allegato:
• Un file ARCHxxx.s, contenente il programma.
• xxx deve essere sostituito con le iniziali dei cognomi dei membri del gruppo in ordine alfabetico.
• Esempio: Marco Vassura e Riccardo Solmi consegnerebbero un file chiamato ARCHsv.s
• Il programma deve iniziare con un commento contenente:
• Nome e Cognome di tutti i membri del gruppo
• Descrizione delle scelte fatte in particolare dei registri che usate.
• Un bytecode di esempio scritto da voi di almeno 10 righe che calcoli qualcosa e metta il risultato in una variabile locale.