Every time I try to understand disassembled code of a compiled Java file, I wondered why some instruction numbers are missing.
A small example:
I disassembled ($ javap -c HelloWorld
) a simple HelloWorld class. Here is the output:
Compiled from "HelloWorld.java"
public class HelloWorld {
public HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello World!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
As you can see, instructions 3 and 4 in the constructor and some in the main method are missing.
Does someone know why these instruction numbers are missing? Are there some bytecode instructions that are hidden for some reason?
The "holes" are where the current instruction's arguments go, see the Java Virtual Machine Specification. It contains a full list of bytecodes in Chapter 6.
For example invokevirtual
and invokespecial
both take 2 arguments, so the next opcode will be found 3 bytes later. In both these cases the parameters (indexbyte1 and indexbyte2) are needed to calculate the position in the constant pool as (indexbyte1 << 8) | indexbyte2)
Javap looks up these values for you, that's the reference in comments after the actual instruction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With