# Kann jemand diesen Java-Code in IJVM-Code schreiben ohne lokalen Variablen, außer a und b?



## berserkerdq2 (23. Apr 2022)

```
Vorgegeben ist:

; main-Methode
main 1 2 // Argumente 0 = OBJREF, lok. Variablen 1 = a, 2 = b
 BIPUSH 15 // a
 ISTORE 1
 BIPUSH 50 // b
 ISTORE 2
 
 BIPUSH 0
 ILOAD 1
 ILOAD 2
 INVOKEVIRTUAL ggt

 ; print
 ILOAD 2
 ILOAD 1
 SPRINT "Ergebnis: ggt("
 IPRINT
 SPRINT ","
 IPRINT
 SPRINT ") = "
 IPRINT
 SPRINT "\n"
 IRETURN
```


----------



## KonradN (24. Apr 2022)

Mir ist gerade nicht ganz bewusst, was Du genau willst. Dein Java Code beschreibt die ggt Methode. Dein Byte-Code eine main Methode. 

In Deiner ggt Methode hast Du keine lokale Variable - du hast lediglich zwei Parameter. Daher sind da keine lokalen Variablen zu entfernen.

In der main Methode kannst Du natürlich die lokalen Variablen entfernen - dazu müsstest Du halt nur direkt den Aufruf machen, also etwas wie:


```
BIPUSH 15 // a
 BIPUSH 50 // b
 INVOKEVIRTUAL ggt

 ; print
 SPRINT "Ergebnis: ggt(15,20) = "
 IPRINT
 SPRINT "\n"
 IRETURN
```

Aber evtl. habe ich Dich auch einfach nicht verstanden - vielleicht schreibst Du erst einmal im Detail, was Du wirklich willst.


----------



## mihe7 (24. Apr 2022)

Ich verstehe die Aufgabe so, dass man die Methode ggt nach IJVM übersetzen soll, ohne dabei (in IJVM) lokale Variablen zum Speichern von Zwischenergebnissen zu verwenden.

Wo nun genau das Problem liegt, ist mir allerdings auch nicht klar.


----------



## berserkerdq2 (24. Apr 2022)

mihe7 hat gesagt.:


> Ich verstehe die Aufgabe so, dass man die Methode ggt nach IJVM übersetzen soll, ohne dabei (in IJVM) lokale Variablen zum Speichern von Zwischenergebnissen zu verwenden.
> 
> Wo nun genau das Problem liegt, ist mir allerdings auch nicht klar.


Genau wir sollen die Methode ggt nach IJVM übersetzen ohne lokale Variablen zum Speichern von Zwischergebnissen zu verwenden, dürfen nur das a und b verwenden, was auch bei der Methode ist und ich habe das nicht hinbekommen. Das oben waren die Vorgaben.

Also das was ich oben eingefügt habe, war einfach nur eine Vorgabe und unten drunter, sollte der Bytecode hin. Also sollen diese Methode ggt dahin übersetzen. Hatten paar Aufgaben, aber bei der komme ich gar nicht weiter.


----------



## httpdigest (24. Apr 2022)

Du hast noch nicht beschrieben, _wo genau_ du denn jetzt ein Problem hast. Kannst du deinen möglichen Gedankengang zur eigenen Lösung der Aufgabe beschreiben und sagen, wo du Fragen hast bzw. wo genau du nicht weiterkommst, nachdem du dir lange genug eigene Gedanken zu einer Lösung gemacht hast?


----------



## berserkerdq2 (24. Apr 2022)

httpdigest hat gesagt.:


> Du hast noch nicht beschrieben, _wo genau_ du denn jetzt ein Problem hast. Kannst du deinen möglichen Gedankengang zur eigenen Lösung der Aufgabe beschreiben und sagen, wo du Fragen hast bzw. wo genau du nicht weiterkommst, nachdem du dir lange genug eigene Gedanken zu einer Lösung gemacht hast?


Aso ja, also mein Problem ist eigentlich, hab bis jetzt immer mit Speicherung der Zwischenergebnissen gearbeitet und noch nie ohne und keinen Plan, wie ich da vorgehen soll.


----------



## httpdigest (24. Apr 2022)

IJVM ist ja eine stackbasierte Maschine. Der Trick ist hierbei, die Veränderung des Stacks zu simulieren und zu schauen, ob das Zwischenergebnis (welches ja auch erstmal auf dem Stack liegt) bereits "an der richtigen Stelle" liegt, um sofort von einem Methodenaufruf (z.B. INVOKEVIRTUAL ggt) konsumiert zu werden. Du brauchst also keine expliziten neuen lokalen Variablen für Zwischenergebnisse, wenn diese Zwischenergebnisse sowieso schon an der richtigen Stelle im Operand-Stack liegen.


----------



## berserkerdq2 (25. Apr 2022)

httpdigest hat gesagt.:


> IJVM ist ja eine stackbasierte Maschine. Der Trick ist hierbei, die Veränderung des Stacks zu simulieren und zu schauen, ob das Zwischenergebnis (welches ja auch erstmal auf dem Stack liegt) bereits "an der richtigen Stelle" liegt, um sofort von einem Methodenaufruf (z.B. INVOKEVIRTUAL ggt) konsumiert zu werden. Du brauchst also keine expliziten neuen lokalen Variablen für Zwischenergebnisse, wenn diese Zwischenergebnisse sowieso schon an der richtigen Stelle im Operand-Stack liegen.


Achsoo! Ich setze mich dann nochmal ran, habe immer Zwischenvariablen genutzt. Danke


----------



## berserkerdq2 (25. Apr 2022)

Könnte jemand von euch ein Beispiel machen? Wie das funktioniert, dass ich das ohne zwischenvariablen mache? Muss auch nicht die Aufgabe sein, kann irgendetwas sein, damit man das mal sieht?


----------



## httpdigest (25. Apr 2022)

meineMethode(5-1, 3) --->

```
BIPUSH 5 ; stack: 5
BIPUSH 1 ; stack: 5, 1
ISUB     ; stack: 4
BIPUSH 3 ; stack: 4, 3
INVOKEVIRTUAL meineMethode
```

Jaa.... INVOKEVIRTUAL braucht eigentlich noch eine OBJREF als erstes Argument, aber IJVM ist seeeeehr merkwürdig, was das angeht. Um "this" auf den Stack zu bekommen, scheint man BIPUSH 0 (also ein Byte-Literal mit Wert = 0) auf den Stack pushen zu müssen, da IJVM keine ALOAD Instruktion hat. Das ist aber _extremst_ weird, weil BIPUSH 0 heißt ja nicht: Lade die OBJREF, die im lokalen Variablenslot 0 liegt (was 'this' entsprechen würde), sondern: lade das Byte mit dem Wert 0 auf den Stack. Und INVOKEVIRTUAL scheint dann den Methodenempfänger als erstes Stack-Argument so zu interpretieren, dass das Byte, was dort liegt, dann halt der lokale Variablenslot ist, wo der Receive als OBJREF gespeichert ist.
Ich finde IJVM extrem unintuitive, was das Handling von Objektreferenzen angeht.


----------

