|
Vergleich: Ausgabe von Innerhalb eines Java Development Kits (JDK) wird das Standard-Tool
javap -c BytecodeExample.class kann eine entsprechende Ausgabe erhalten werden (linke Spalte der Tabelle). Tabelle 5.3. Vergleich der Ausgabe des Klassendatei-Disassemblers
Der in der Tabelle angegebene Jasmin-Quelltext wird vom Assembler
übersetzt. Da aber die Direktive > javap -verbose BytecodeExample
Compiled from "BytecodeExample.java"
public class BytecodeExample extends java.lang.Object
SourceFile: "BytecodeExample.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #6.#17; // java/lang/Object."<init>":()V
const #2 = Field #18.#19; // java/lang/System.out:Ljava/io/PrintStream;
const #3 = Method #20.#21; // java/io/PrintStream.println:(I)V
const #4 = Method #5.#22; // BytecodeExample.method1:()V
const #5 = class #23; // BytecodeExample
const #6 = class #24; // java/lang/Object
const #7 = Asciz <init>;
const #8 = Asciz ()V;
const #9 = Asciz Code;
const #10 = Asciz LineNumberTable;
const #11 = Asciz method1;
const #12 = Asciz StackMapTable;
const #13 = Asciz main;
const #14 = Asciz ([Ljava/lang/String;)V;
const #15 = Asciz SourceFile;
const #16 = Asciz BytecodeExample.java;
const #17 = NameAndType #7:#8;// "<init>":()V
const #18 = class #25; // java/lang/System
const #19 = NameAndType #26:#27;// out:Ljava/io/PrintStream;
const #20 = class #28; // java/io/PrintStream
const #21 = NameAndType #29:#30;// println:(I)V
const #22 = NameAndType #11:#8;// method1:()V
const #23 = Asciz BytecodeExample;
const #24 = Asciz java/lang/Object;
const #25 = Asciz java/lang/System;
const #26 = Asciz out;
const #27 = Asciz Ljava/io/PrintStream;;
const #28 = Asciz java/io/PrintStream;
const #29 = Asciz println;
const #30 = Asciz (I)V;
{
public BytecodeExample();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
public static void method1();
Code:
Stack=2, Locals=2, Args_size=0
0: iconst_0
1: istore_0
2: iconst_0
3: istore_1
4: iload_1
5: bipush 10
7: if_icmpge 20
10: iload_0
11: iconst_2
12: iadd
13: istore_0
14: iinc 1, 1
17: goto 4
20: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
23: iload_0
24: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
27: return
LineNumberTable:
line 6: 0
line 7: 2
line 8: 10
line 7: 14
line 10: 20
line 11: 27
StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 4
locals = [ int, int ]
frame_type = 250 /* chop */
offset_delta = 15
public static void main(java.lang.String[]);
Code:
Stack=0, Locals=1, Args_size=1
0: invokestatic #4; //Method method1:()V
3: return
LineNumberTable:
line 14: 0
line 15: 3
}Die mit dem Jasmin-Quelltext aus Tabelle 5.3 erzeugte
Klassendatei enthält keine LineNumberTable-Attribute und kein StackMapTable-Attribut.
Diese können aber unter Verwendnung der Direktiven Listing 5.22. ; BytecodeExample.j .bytecode 50.0 .source BytecodeExample.java .class public BytecodeExample .super java/lang/Object .method public <init>()V .limit stack 1 .limit locals 1 .line 3 0: aload_0 1: invokespecial java/lang/Object/<init>()V 4: return .end method .method public static method1()V .limit stack 2 .limit locals 2 .line 6 0: iconst_0 1: istore_0 .line 7 2: iconst_0 3: istore_1 Label4: 4: iload_1 5: bipush 10 7: if_icmpge Label20 .line 8 10: iload_0 11: iconst_2 12: iadd 13: istore_0 .line 7 14: iinc 1 1 17: goto Label4 Label20: .line 10 20: getstatic java/lang/System/out Ljava/io/PrintStream; 23: iload_0 24: invokevirtual java/io/PrintStream/println(I)V .line 11 27: return ; append_frame (frameNumber = 0) ; frame_type = 253, offset_delta = 4 ; frame bytes: 253 0 4 1 1 .stack offset 4 locals Integer locals Integer .end stack ; chop_frame (frameNumber = 1) ; frame_type = 250, offset_delta = 15 ; frame bytes: 250 0 15 .stack offset 20 locals Integer .end stack .end method .method public static main([Ljava/lang/String;)V .limit stack 0 .limit locals 1 .line 14 0: invokestatic BytecodeExample/method1()V .line 15 3: return .end method Die Ausgabe zu StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 4
locals = [ int, int ]
frame_type = 250 /* chop */
offset_delta = 15Der Zusammenhang dieser Angabe mit den
Bytecodierung eines Default-Konstruktors Die Codierung des Default-Konstruktors aus Listing 5.1
innerhalb der Klassendatei .method public <init>()V .limit stack 1 .limit locals 1 aload_0 invokespecial java/lang/Object/<init>()V return .end method Der Default-Konstruktor wird durch die JVM-Befehle
invokespecial java/lang/Object/<init>()V Klassenname: java/lang/Object Methodenname: <init> Methodendeskriptor: ()V Auf die Mnemonik (1). Konstante (Methodref): Methode von Klasse #(2), Name/Typ #(4) (2). Konstante (Class): Klasse #(3) (3). Konstante (Utf8): java/lang/Object (4). Konstante (NameAndType): Name #(5), Typ #(6) (5). Konstante (Utf8): <init> (6). Konstante (Utf8): ()V Die Nummerierung der Konstanten wurde in Klammern gesetzt, da die reale Position
der Konstanten im Konstantenpool der erzeugten Klassendatei von der Implementierung
des Assemblers abhängt. In der von Im Konstantenpool:
(1). Konstante: 0a 00 02 00 04
(2). Konstante: 07 00 03
(3). Konstante: 01 00 10 6a 61 76 61 2f 6c 61 32 6e 67 2f 4f 62 6a 65 63 74
(4). Konstante: 0c 00 05 00 06
(5). Konstante: 01 00 06 3c 69 6e 69 74 3e
(6). Konstante: 01 00 03 28 29 56
(7). Konstante: 01 00 04 43 6f 64 65
Im Methodenbereich:
00 01 00 05 00 06 00 01 00 07 00 00 00 11
00 01 00 01 00 00 00 05 2a b7 00 01 b1
00 00 00 00Für den Konstantenpool wird zu den bereits genannten sechs Konstanten noch eine weitere Konstante benötigt, die den Namen des Methodenattributs speichert. Die erste notierte Zeile im Methodenbereich bedeutet: 00 01 - Konstruktor wurde mit public deklariert.
00 05 - Name des Konstruktors steht in der 5. Konstanten.
00 06 - Deskriptor des Konstruktors steht in der 6. Konstanten.
00 01 - Es existiert ein einziges Methodenattribut.
00 07 - Der Name des Methodenattributs steht in der 7. Konstanten.
(Typ: Utf8, repräsentiert die Zeichenkette "Code")
00 00 00 11 - Die Länge des Methodenattributs besteht aus 17 Bytes.Die zweite notierte Zeile im Methodenbereich beginnt mit |
||||||||||
|
|
||||||||||