Недостающие номера команд в выводе javap
Каждый раз, когда я пытаюсь понять дизассемблированный код скомпилированного файла Java, я удивляюсь, почему отсутствуют некоторые номера команд.
Небольшой пример:
Я разобрал ($ javap -c HelloWorld
) простой класс HelloWorld. Вот вывод:
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
}
Как видите, инструкции 3 и 4 в конструкторе, а некоторые в методе main отсутствуют.
Кто-нибудь знает, почему эти номера инструкций отсутствуют? Существуют ли инструкции по байт-коду, которые по какой-то причине скрыты?
2 ответа
"Дыры" - это то место, куда идут аргументы текущей инструкции, см. Спецификацию виртуальной машины Java. Он содержит полный список байт-кодов в главе 6.
Например invokevirtual
а также invokespecial
оба принимают 2 аргумента, поэтому следующий код операции будет найден через 3 байта. В обоих этих случаях параметры (indexbyte1 и indexbyte2) необходимы для расчета позиции в константном пуле как (indexbyte1 << 8) | indexbyte2)
Javap ищет эти значения для вас, это ссылка в комментариях после фактической инструкции.
Это не номера команд, а смещение байтов команды относительно метода.
Я все еще ищу официальную документацию на этот счет, но эта ссылка подтверждает это.