IJVM Architettura degli Elaboratori Danilo Dessì danilo_dessi@unica.it
Instruction set
Istruzioni di salto BRANCH Istruzione GOTO label IFEQ label IFLT label IF_ICMPEQ label Significato Salta in modo incondizionato all istruzione etichettata da label Pop della parola in cima allo stack; se la parola vale 0 salta all istruzione etichettata da label Pop della parola in cima allo stack; se la parola ha un valore negativo salta all istruzione etichettata da label Pop di due parole dalla cima dello stack; se le parole sono uguali salta all istruzione etichettata da label Salto incondizionato: quando si forza il programma a continuare la sua esecuzione da un istruzione in una posizione specifica Salto condizionato: quando al verificarsi di una condizione si forza il programma a continuare la sua esecuzione da un istruzione specifica
Instruction Set METODI Istruzione INVOKEVIRTUAL m IRETURN ALTRE Istruzione HALT IINC v n ERR IN OUT NOP WIDE Significato Chiama il metodo m Termina l esecuzione del metodo corrente e restituisce il controllo al metodo chiamante Significato Blocca l esecuzione del programma nel simulatore Modifica la variabile v sommandoci n Scrive un messaggio di errore e blocca il simulatore Legge un carattere dal buffer della testiera e lo salva in cima allo stack; se il buffer è vuoto salva 0 Pop della parola in cima allo stack e la stampa in out Istruzione vuota: non fa nulla Indica che la prossima istruzione sarà a 16 bit
Costrutto if-else Il costrutto if in un linguaggio ad alto livello ha la forma if (condizione) istruzione/i if (condizione) istruzione/i else istruzione/i Nei linguaggi più basso livello non abbiamo il costrutto if In IJVM si utilizzano le istruzioni di branch che controllano il valore (o i valori) in cima allo stack e in base al risultato della verifica saltano a un istruzione specifica tramite un etichetta
Esempio costrutto if a = 5 b = 7 c = 6 If ( a <= 8 ) a = b c Inizializzazione variabili a = 8 a < 8.main.var a b c.end-var BIPUSH 0x5 BIPUSH 0x7 ISTORE b BIPUSH 0x6 ISTORE c BIPUSH 0x8 IF_ICMPEQ vero BIPUSH 0x8 IFLT vero HALT vero: ILOAD c HALT.end-main Istruzioni blocco if
Esempio costrutto if-else a = 5 b = 7 c = 6 If ( a <= 8 ) a = b c else a = b + c Inizializzazione variabili a = 8 a < 8.main.var a b c.end-var BIPUSH 0x5 BIPUSH 0x7 ISTORE b BIPUSH 0x6 ISTORE c BIPUSH 0x8 IF_ICMPEQ vero BIPUSH 0x8 IFLT vero vero: ILOAD c HALT.end-main Istruzioni blocco if Istruzioni blocco else ILOAD c HALT
Costrutti iterativi Costrutti iterativi while (condizione) istruzione/i for (i=0, i < limite; i = i + 1) istruzione/i In IJVM si utilizzano le stesse istruzioni di branch utilizzate per la selezione Si utilizza anche il salto incondizionato: dopo che eseguo il blocco di istruzioni salto alle istruzioni che verificano la condizione Attenzione ai cicli infiniti!
Esempio costrutto while.main.main while ( a < b ) { a = a * 3 b = b * 2 } ciclo: IFLT blocco GOTO continuo blocco: ISTORE b GOTO ciclo continuo:.end-main ciclo: IFEQ continuo IFLT continuo ISTORE b GOTO ciclo continuo:.end-main
Esempio costrutto for.main for( i = 0; i <= 10; i = i + 1 ) a = a * 3 BIPUSH 0x0 ISTORE i ciclo: BIPUSH 0xa ILOAD i IFLT continuo blocco: IINC i 1 GOTO ciclo continuo:.end-main
Stack & Metodi Ogni volta che si richiama un metodo è necessario inserire il riferimento al metodo e i parametri sullo stack (se sono presenti nella firma), che formano il blocco del metodo Per ogni invocazione il metodo può accedere alle sole variabili nel proprio blocco. Il blocco riservato per ogni metodo che si esegue è detto record di attivazione (lo vedrete in dettaglio in altri corsi ) Per noi nel record ci sono il riferimento (semplicemente una costante che chiamiamo OBJREF), i parametri del metodo e le variabili Se la funzione è ricorsiva ogni chiamata porterà alla creazione di un nuovo blocco in cima allo stack Il blocco che sta in cima determina quale è il metodo che si sta eseguendo in quel momento, i blocchi inferiori appartengono ai metodi che sono sospesi in attesa del risultato della funzione chiamata Al termine dell esecuzione della funzione con l istruzione IRETURN il blocco viene deallocato, in cima allo stack viene posto il valore di ritorno e si riprende l esecuzione dalla funzione chiamante
Moltiplicazione.constant OBJREF 0x40.end-constant.main.end-main.var i j r.end-var BIPUSH 0x5 ISTORE i BIPUSH 0x3 ISTORE j LDC_W OBJREF ILOAD i ILOAD j INVOKEVIRTUAL mul ISTORE r HALT.method mul( i, j ) ciclo:.var r.end-var BIPUSH 0x0 ISTORE r ILOAD i IFEQ fine ILOAD j IFEQ fine ILOAD i ILOAD r ISTORE r IINC j -1 GOTO ciclo fine:.end-method ILOAD r IRETURN
Esercizio Scrivere il codice IJVM per i metodi che calcolano la divisione intera (sia quoziente sia resto) 20 min
Soluzione.method div (a,b).method mod (a,b) loop: IFEQ end_loop IFLT end_loop GOTO loop end_loop: IRETURN.end-method.var q.end-var BIPUSH 0x0 ISTORE q loop: IFEQ end_loop IFLT end_loop IINC q 0x1 GOTO loop end_loop: ILOAD q IRETURN.end-method