Virtuální procesor pro jazyk Java
Manipulace se zásobníkem
Volání každé metody má svůj soukromý zásobník
operandů, jenž se používá pro předávání argumentů
metodám a pro uložení návratové hodnoty. Metody deklarují,
jak velký zásobník operandů potřebují.
Ukládání konstant na zásobník
Jméno |
Popis |
bipush <val> |
uloží na zásobník jednobytovou konstantu se
znaménkem |
sipush <val> |
uloží na zásobník dvoubytovou konstantu se
znaménkem |
ldc <index> |
uloží na zásobník konstantu ze seznamu konstant |
iconst_m1 |
uloží na zásobník konstantu -1 |
iconst_<n> |
uloží na zásobník konstantu <n>, n = 0, 1,
2, 3, 4, 5 |
Manipulace se zásobníkem
Jméno |
Popis |
pop |
odstraní položku na vrcholu zásobníku |
dup |
duplikuje položku na vrcholu zásobníku |
swap |
vymění položky na vrcholu zásobníku |
Lokální proměnné
Volání každé metody má svou soukromou oblast lokálních
proměnných, kde jsou uloženy argumenty metody a další
lokální proměnné. Argumenty jsou do lokálních proměnných
přesunuty z vrcholu zásobníku při volání metody. Každá
proměnná má přidělen index počínaje indexem 0, pomocí
něhož je možné se na proměnné odkazovat. S lokálními
proměnnými typu char a boolean se pracuje jako s proměnnými
typu int, tj. v plné délce 32 bitů.
Ukládání proměnných na zásobník
Jméno |
Popis |
iload <index> |
uloží na zásobník hodnotu lokální proměnné
typu int na zadaném indexu |
iload_<index> |
-""- (zkrácená varianta, index = 0, 1, 2,
3) |
aload <index> |
uloží na zásobník hodnotu lokální proměnné
typu reference na zadaném indexu |
aload_<index> |
-""- (zkrácená varianta, index = 0, 1, 2,
3) |
Úschova proměnných z vrcholu zásobníku
Jméno |
Popis |
istore <index> |
uloží hodnotu z vrcholu zásobníku do lokální
proměnné typu int na zadaném indexu |
istore_<index> |
-""- (zkrácená varianta, index = 0, 1, 2,
3) |
astore <index> |
uloží hodnotu z vrcholu zásobníku do lokální
proměnné typu reference na zadaném indexu |
astore_<index> |
-""- (zkrácená varianta, index = 0, 1, 2,
3) |
Doplňkové instrukce pro lokální proměnné
Jméno |
Popis |
iinc <index> <val> |
zvýší hodnotu lokální proměnné typu int na
zadaném indexu o hodnotu <val> |
Pole
Pole mají v jazyce Java statut objektů a pro každé pole je
tedy třeba voláním operátoru new přidělit
potřebný prostor. Výsledkem instrukcí newarray
a anewarray
je reference
na pole, která se dále používá při jakémkoliv přístupu k
poli a jeho prvkům. Pole mohou obsahovat i hodnoty typu boolean
a char, pro které jsou k dispozici samostatné přístupové
operace, na rozdíl od jednoduchých lokálních proměnných
těchto typů.
Vytváření polí
Jméno |
Popis |
newarray <typ> |
vytvoří pole hodnot jednoduchého typu; počet
položek je na vrcholu zásobníku |
anewarray <typ> |
vytvoří pole objektů zadaného typu; počet
položek je na vrcholu zásobníku |
Čtení prvků pole
Jméno |
Popis |
iaload |
získá hodnotu prvku pole hodnot typu int; na
vrcholu zásobníku je adresa pole a hodnota indexu |
aaload |
získá hodnotu prvku pole hodnot typu reference; na
vrcholu zásobníku je adresa pole a hodnota indexu |
baload |
získá hodnotu prvku pole hodnot typu boolean; na
vrcholu zásobníku je adresa pole a hodnota indexu |
caload |
získá hodnotu prvku pole hodnot typu char; na
vrcholu zásobníku je adresa pole a hodnota indexu |
Zápis prvků pole
Jméno |
Popis |
iastore |
uloží hodnotu do prvku pole hodnot typu int; na
vrcholu zásobníku je adresa pole, index a hodnota |
aastore |
uloží hodnotu do prvku pole hodnot typu reference;
na vrcholu zásobníku je adresa pole, index a hodnota |
bastore |
uloží hodnotu do prvku pole hodnot typu boolean; na
vrcholu zásobníku je adresa pole, index a hodnota |
castore |
uloží hodnotu do prvku pole hodnot typu char; na
vrcholu zásobníku je adresa pole, index a hodnota |
Objekty
Jazyk MiniJava pracuje pouze se statickými objekty (tj.
takovými, které mají pouze statické metody a statické
proměnné třídy - objekt reprezentující hlavní program a
objekt reprezentující modul IO) a s konstantními objekty typu
java.lang.String. Pro žádný z těchto objektů nejsou nutné
explicitní operace pro vytvoření, pouze pro objekt hlavního
programu se používají operace zpřístupňující statické
("globální") proměnné.
Jméno položky musí obsahovat celou cestu, tj. jméno
třídy a jméno položky oddělené lomítkem. Typ položky je
kódován takto:
I |
int |
C |
char |
Z |
boolean |
[t |
t[] |
Ljava/lang/String; |
String |
Manipulace s položkami objektů
Jméno |
Popis |
getstatic "položka" "typ" |
uloží hodnotu statické proměnné třídy na
vrchol zásobníku |
putstatic "položka" "typ" |
uloží hodnotu z vrcholu zásobníku do statické
proměnné třídy |
Aritmetické operace
Aritmetické operace pracují pouze nad hodnotami typu int.
Binární operátory očekávají na vrcholu zásobníku dvě
hodnoty typu int, unární operátor očekává jedinou hodnotu
typu int. Výsledek operace nahradí na vrcholu zásobníku
operandy.
Aritmetické operátory
Jméno |
Popis |
iadd |
sečte hodnoty typu int z vrcholu zásobníku a
nahradí je výsledkem |
isub |
odečte hodnoty typu int z vrcholu zásobníku a
nahradí je výsledkem |
imul |
vynásobí hodnoty typu int z vrcholu zásobníku a
nahradí je výsledkem |
idiv |
vydělí hodnoty typu int z vrcholu zásobníku a
nahradí je výsledkem dělení |
irem |
vydělí hodnoty typu int z vrcholu zásobníku a
nahradí je zbytkem po dělení |
ineg |
změní znaménko hodnoty na vrcholu zásobníku |
Řízení běhu programu
Pro řízení běhu programu jsou k dispozici operace
porovnávající vrchol zásobníku s nulou nebo dvě hodnoty
typu int na vrcholu zásobníku. Porovnávané hodnoty jsou ze
zásobníku vždy odstraněny a v případě splnění podmínky
se řízení přesune na uvedené místo v programu.
Skoky
Jméno |
Popis |
ifeq <lbl> |
skok, je-li na vrcholu zásobníku nulová hodnota
typu int |
iflt <lbl> |
skok, je-li na vrcholu zásobníku hodnota typu int
menší než nula |
ifle <lbl> |
skok, je-li na vrcholu zásobníku hodnota typu int
menší nebo rovna nule |
ifne <lbl> |
skok, je-li na vrcholu zásobníku nenulová hodnota
typu int |
ifgt <lbl> |
skok, je-li na vrcholu zásobníku hodnota typu int
větší než nula |
ifge <lbl> |
skok, je-li na vrcholu zásobníku hodnota typu int
větší nebo rovna nule |
if_icmpeq <lbl> |
skok, rovnají-li se hodnoty typu int na vrcholu
zásobníku |
if_icmpne <lbl> |
skok, nerovnají-li se hodnoty typu int na vrcholu
zásobníku |
if_icmplt <lbl> |
skok, je-li jedna hodnota typu int na vrcholu
zásobníku menší než druhá |
if_icmpgt <lbl> |
skok, je-li jedna hodnota typu int na vrcholu
zásobníku větší než druhá |
if_icmple <lbl> |
skok, je-li jedna hodnota typu int na vrcholu
zásobníku menší nebo rovna druhé |
if_icmpge <lbl> |
skok, je-li jedna hodnota typu int na vrcholu
zásobníku větší nebo rovna druhé |
goto <lbl> |
nepodmíněný skok |
Volání metod a návrat
Jazyk MiniJava podporuje pouze statické metody tříd. Před
jejich voláním je třeba uložit hodnoty argumentů na vrchol
zásobníku postupně zleva doprava. Po vyhodnocení metody jsou
argumenty odstraněny a jsou nahrazeny případnou návratovou
hodnotou. Poslední instrukcí metody musí být některá
varianta instrukce return
v závislosti na typu návratové hodnoty metody.
Název metody musí obsahovat celou cestu, tj. jméno třídy
a jméno metody oddělené lomítkem. Typ metody je řetězec
tvořený seznamem typů argumentů v kulatých závorkách, za
nimiž následuje typ výsledku (V pro void).
Jméno |
Popis |
invokestatic "metoda" "typ" |
volání statické metody třídy |
return |
návrat z metody bez návratové hodnoty |
ireturn |
návrat z metody s návratovou hodnotou typu int na
zásobníku |
areturn |
návrat z metody s návratovou hodnotou typu
reference na zásobníku |