每次我试图理解编译的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以及主方法中的一些指令都丢失了。
有人知道为什么这些指令号不见了吗?是否有一些字节码指令由于某种原因而被隐藏?
"holes"是当前指令参数所在的位置,请参阅Java虚拟机规范。它包含了第6章中字节码的完整列表。
例如,invokevirtual
和invokespecial
都有2个参数,因此下一个操作码将在3个字节后找到。在这两种情况下,需要参数(indexbyte1和indexbyte2(来将常量池中的位置计算为(indexbyte1 << 8) | indexbyte2)
Javap为您查找这些值,这是实际指令之后注释中的引用。
这些不是指令号,它们是指令相对于方法的字节偏移量。
我仍在寻找官方文档,但这个链接证实了这一点。