Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

Those aren't instruction numbers, they're the byte offset of the instruction relative to the method.

I'm still looking for official documentation to that end, but this link confirms it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top