Continuiamo il nostro esempio, introducendo il livello ISA della macchina che sarà interpretata dal microprogramma eseguito nella microarchitettura mostrata in Esempio microarchitettura (Mic-1). Per comodità a volte ci riferiremo all’architettura dell’insieme d’istruzioni ( ISA ) come macroarchitettura. Però prima di descrivere IJVM faremo una digressione che ci aiuterà dopo.

Stack

Tutti i linguaggi di programmazione supportano il concetto di procedure ( o metodi ), dotate di un insieme di variabili locali. Ma in quale parte della memoria bisogna memorizzare queste variabili ? La soluzione è di memorizzare le variabili in un’area della memoria chiamata stack ( o pila ) ovvero una struttura dati che segue la filosofia LIFO ( Last-In-First-Out ). Ogni variabile è “puntata” da LV, ovvero un registro che punta alla base delle variabili locali per la procedura corrente. Mentre un altro registro SP punta alla variabile che si trova nella locazione più alta dell’intero stack.
Per esempio :

consideriamo solo (a), questa struttura dati compresa da SP a LV, è chiamata local variable frame ( blocco delle variabili locali ) di A in questo caso.

Questo tipo di organizzazione dei dati permette di gestire anche situazioni di chiamate ricorsive ( ovvero procedure che chiamano se stesse ).

JVM e IJVM utilizzano lo stack anche per memorizzare gli operandi durante un calcolo di un’espressione aritmetica ( stack degli operandi ) ( non lo fanno tutti ).

Modello della memoria di IJVM

La memoria da 4 GB può essere concepita come un array di :

  • 4.294.967.296 byte
  • 1.073.741.824 (2^30) word da 4 byte l'una

Inoltre la memoria è divisa in 4 aree principali :

  • Constant Pool ( Zona delle costanti ) :
    • area di memoria di sola lettura
    • contiene costanti, stringhe e puntatori ad altre aree
    • viene caricata all’avvio del programma
    • viene utilizzato un registro CPP ( Constant Pool Pointer ) che punta al primo elemento
  • Local Variable Frame
  • Operand Stack ( stack degli operandi )
  • Method Area ( Area per le procedure )
    • contiene il codice del programma
    • viene utilizzato PC per puntare alla prossima istruzione da eseguire

Insieme delle istruzioni IJVM

La seguente figura mostra l’insieme delle istruzioni IJVM :

dove alcune operazioni permettono di :

  • inserire nello stack ( push ) una word ( es. BIPUSH, DUP, LDC_W, ILOAD )
  • prendere dallo stack ( pop ) una variabile è inserirla in una variabile : ISTORE
  • eseguire operazioni ( utilizzano le due word in cima allo stack )
    • aritmetiche : IADD, ISUB
    • logiche ( booleane ) : IAND e IOR
  • fare “salti” ( cambiano il PC in base ad offset ):
    • non condizionale : GOTO
    • condizionali : IFEQ, IFLT, IF_ICMPEQ

Vediamo un esempio da codice Java a IJVM :

i = j + k;
if ( j == 3 )
	k = 0;
else 
	j = j - 1; 

Supponendo che i sia la variabile locale 1, j sia la 2 e k sia la 3 :

ILOAD j  // pusha j  
ILOAD k  // pusha k 
IADD     // j + k e lo pusha 
ISTORE i // pop j + k e la mette in i come variabile (non pusha)
ILOAD i   // pusha i 
BIPUSH 3  // pusha 3 
IF_ICMPEQ L1 // compara i e 3 e se sono uguali vai a offest +L1 
ILOAD j      // pusha j 
BIPUSH 1     // pusha 1 
ISUB        // j - 1 e lo pusha 
ISTORE j
GOTO L2     // vai a end 
 
L1 : BIPUSH 0 // pusha 0 
	ISTORE k // k = 0
 
L2 : // end