javaseiten.de   |   Version 0.6
 

4.11. JVM-Befehlssatz: Kurzbeschreibung G

 

 

Befehl Operandenstapel Opcode
getfield indexbyte1 indexbyte2 ..., objectref --> ..., value 0xb4

Lese ein Feld (Instanzvariable) einer Objekts aus.

Bezeichner Typ Beschreibung
indexbyte1 Vorzeichenloses Byte Index im (Laufzeit-)Konstantenpool.
indexbyte2 Vorzeichenloses Byte Index im (Laufzeit-)Konstantenpool.
objectref reference Referenz auf ein Objekt.
value Abhängig vom Typ des Feldes. Wert des Feldes.

Mit Hilfe von indexbyte1 und indexbyte2 wird ein Index im (Laufzeit-)Konstantenpool der aktuellen Klasse berechnet: (indexbyte1 << 8) | indexbyte2. Durch diesen Index (Konstante vom Typ Feldreferenz) und der Objekreferenz kann der Wert value des Feldes ermittelt und anschließend auf den Operandenstapel der entsprechenden Methode gelegt werden.

Beispiel:

public class Test {

  int a = 3;                                     public Test();
                                                 Code:
                                                  0: aload_0
                                                  1: invokespecial #1; //Method
                                                     java/lang/Object."<init>"
                                                     :()V
                                                  4: aload_0
                                                  5: iconst_3
                                                  6: putfield #2; //Field a:I
                                                  9: return
 
  public static void main(String[] args) {       public static void main
                                                 (java.lang.String[]);
                                                 Code:
    Test t = new Test();                          0: new #3; //class Test
                                                  3: dup
                                                  4: invokespecial #4; //Method
                                                     "<init>":()V
                                                  7: astore_1
    t.a = t.a + 1;                                8: aload_1
                                                  9: aload_1
                                                 10: getfield #2; //Field a:I
                                                 13: iconst_1
                                                 14: iadd
                                                 15: putfield #2; //Field a:I
  }                                              18: return
}

Der Instanzvariablen a wird im Quelltext der Wert 3 zugewiesen. Durch diese Initialisierung wird innerhalb des Methodenbereiches der bei der Übersetzung entstehenden Klassendatei, eine Instanz-Initialisierungsmethode (Konstruktor) erzeugt. Der paramterlose Default-Konstruktor wird durch den Compiler automatisch generiert. Mit Hilfe des Klassendatei-Disassemblers javap erfolgt für diese spezielle Methode die Ausgabe nach der Bezeichnung public Test() auf der rechten Seite der Übersicht.

Der Befehl getfield #2 wird innerhalb der Klassendatei durch die drei Bytes b4 00 02 codiert. Die für diesen Befehl indizierte Konstante befindet sich an 2. Stelle im Konstantenpool.

Es sind 19 Konstanten im Konstantenpool enthalten.
1. Konstante: Methode von Klasse #5, Name/Typ #16
2. Konstante: Feld von Klasse #3, Name/Typ #17
3. Konstante: Klasse #18
4. Konstante: Methode von Klasse #3, Name/Typ #16
5. Konstante: Klasse #19
6. Konstante: Utf8 a
7. Konstante: Utf8 I
8. Konstante: Utf8 <init>
9. Konstante: Utf8 ()V
10. Konstante: Utf8 Code
11. Konstante: Utf8 LineNumberTable
12. Konstante: Utf8 main
13. Konstante: Utf8 ([Ljava/lang/String;)V
14. Konstante: Utf8 SourceFile
15. Konstante: Utf8 Test.java
16. Konstante: Name #8, Typ #9
17. Konstante: Name #6, Typ #7
18. Konstante: Utf8 Test
19. Konstante: Utf8 java/lang/Object

Mit Hilfe der 2. Konstanten kann festgestellt werden, dass die Instanzvariable aus der Klasse Test stammt, der Name der Variablen a ist und die Variable den Typ int hat (für eine Variable von diesem Typ ist der zugehörige Felddeskriptor der Buchstabe I).

Neben getfield zum Auslesen des Inhalts einer Instanzvariablen wird der Befehl putfield verwendet, um einer Instanzvariablen einen Wert zuzuweisen.

 

 

getstatic indexbyte1 indexbyte2 ... --> ..., value 0xb2

Lese ein statisches Feld (statische Variable, Klassenvariable) einer Klasse aus.

Bezeichner Typ Beschreibung
indexbyte1 Vorzeichenloses Byte Index im (Laufzeit-)Konstantenpool.
indexbyte2 Vorzeichenloses Byte Index im (Laufzeit-)Konstantenpool.
value Abhängig vom Typ des statischen Feldes. Wert des statischen Feldes.

Mit Hilfe von indexbyte1 und indexbyte2 wird ein Index im (Laufzeit-)Konstantenpool der aktuellen Klasse berechnet: (indexbyte1 << 8) | indexbyte2. Durch diesen Index (Konstante vom Typ Feldreferenz) kann der Wert value des statischen Feldes ermittelt und anschließend auf den Operandenstapel der entsprechenden Methode gelegt werden.

Beispiel:

public class Test {

  static int a = 3;                               static {};
                                                  Code:
                                                  0: iconst_3
                                                  1: putstatic #2; //Field a:I
                                                  4: return
 
  public static void main(String[] args) {        public static void main
                                                  (java.lang.String[]);
                                                  Code:
    a = a + 1;                                    0: getstatic #2; //Field a:I
                                                  3: iconst_1
                                                  4: iadd
                                                  5: putstatic #2; //Field a:I
                                                  8: return
  }
}

Der statischen Variablen a wird im Quelltext der Wert 3 zugewiesen. Durch diese Initialisierung wird innerhalb des Methodenbereiches der bei der Übersetzung entstehenden Klassendatei, eine Klassen-Initialisierungsmethode erzeugt. Mit Hilfe des Klassendatei-Disassemblers javap erfolgt für diese spezielle Methode die Ausgabe nach der Bezeichnung static {} auf der rechten Seite der Übersicht.

Neben getstatic zum Auslesen eines statischen Feldes wird der Befehl putstatic verwendet, um einem statischen Feld einen Wert zuzuweisen. Der Wert, der zugewiesen werden soll befindet sich auf dem Operandenstapel und die Informationen zum statischen Feld stehen innerhalb des (Laufzeit-)Konstantenpools der zugehörigen Klassendatei (im Beispiel Test.class). Der Befehl putstatic #2 bedient sich dabei der 2. Konstanten im Pool.

Es sind 19 Konstanten im Konstantenpool enthalten.
1. Konstante: Methode von Klasse #4, Name/Typ #16
2. Konstante: Feld von Klasse #3, Name/Typ #17
3. Konstante: Klasse #18
4. Konstante: Klasse #19
5. Konstante: Utf8 a
6. Konstante: Utf8 I
7. Konstante: Utf8 <init>
8. Konstante: Utf8 ()V
9. Konstante: Utf8 Code
10. Konstante: Utf8 LineNumberTable
11. Konstante: Utf8 main
12. Konstante: Utf8 ([Ljava/lang/String;)V
13. Konstante: Utf8 <clinit>
14. Konstante: Utf8 SourceFile
15. Konstante: Utf8 Test.java
16. Konstante: Name #7, Typ #8
17. Konstante: Name #5, Typ #6
18. Konstante: Utf8 Test
19. Konstante: Utf8 java/lang/Object

Mit Hilfe der 2. Konstanten kann die Klasse, in der das statische Feld deklariert ist, der Name des Feldes und der Typ des Feldes (Felddeskriptor) ermittelt werden.

 

 

goto branchbyte1 branchbyte2 ... --> ... 0xa7

Führe eine unbedingte Verzweigung aus.

Bezeichner Typ Beschreibung
branchbyte1 Vorzeichenloses Byte Zahlenwert zur Berechnung eines Verzweigungs-Offsets.
branchbyte2 Vorzeichenloses Byte Zahlenwert zur Berechnung eines Verzweigungs-Offsets.

Aus den vorzeichenlosen Verzweigungsbytes wird ein vorzeichenbehafteter Offset berechnet: (branchbyte1 << 8) | branchbyte2. Der Programmzähler (PC) zeigt auf den Operationscode der Verzweigungsanweisung. Das Programm wird an der Stelle des Offsets bezüglich des PC fortgesetzt. Das Ziel der Verzweigung muss innerhalb des Bytecodes der Methode liegen, von der die Verzweigung ausgeht.

Beispiel:

int a = 3;                    0: iconst_3
                              1: istore_1
boolean c = (a == 0);         2: iload_1
                              3: ifne 10
                              6: iconst_1
                              7: goto 11
                             10: iconst_0
                             11: istore_2

Die goto-Anweisung wird im Beispiel verwendet, um einen Vergleich einer int-Zahl gegenüber 0 zu realisieren. Der JVM-Befehl goto 11 wird innerhalb einer Klassendatei durch die drei Bytes a7 00 04 codiert. Der Offset berechnet sich aus den letzten beiden Bytes und hat den dezimalen Wert 4. Der Operationscode der Verzweigungsanweisung steht an Bytecodestelle 7. Das Programm wird durch die unbedingte Verzweigung an Bytecodestelle 11 (7+4) fortgesetzt.

 

 

goto_w branchbyte1 branchbyte2 branchbyte3 branchbyte4 ... --> ... 0xc8

Unbedingte Verzweigung (erweiterter Verzweigungsoffset).

Bezeichner Typ Beschreibung
branchbyte1 Vorzeichenloses Byte Zahlenwert zur Berechnung eines Verzweigungs-Offsets.
branchbyte2 Vorzeichenloses Byte Zahlenwert zur Berechnung eines Verzweigungs-Offsets.
branchbyte3 Vorzeichenloses Byte Zahlenwert zur Berechnung eines Verzweigungs-Offsets.
branchbyte4 Vorzeichenloses Byte Zahlenwert zur Berechnung eines Verzweigungs-Offsets.

Die Verwendung des Befehls goto ermöglicht relative Sprünge von -32768 bzw. +32767, ausgehend von der Bytecodestelle des Opcodes des Sprungbefehls. Mit goto_w steht ein erweiterter Verzweigungsoffset zur Verfügung, da bei diesem Befehl vier Verzweigungsbytes zur Verfügung stehen. Der vorzeichenbehaftete 32-Bit-Offset berechnet sich dabei wie folgt: (branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4.

Beispiel: Siehe dazu goto.

 

 

 

Diese Seite nutzt Google-Dienste - siehe dazu Datenschutz.

Copyright © 2006, 2007 Harald Roeder