每当我尝试理解已编译的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方法中的指令都缺失。
有人知道为什么缺少这些指令编号吗?是否有一些由于某种原因隐藏的字节码指令?
答案 0 :(得分:7)
&#34;洞&#34;是当前指令的参数,请参阅Java Virtual Machine Specification。它包含Chapter 6中的完整字节码列表。
例如invokevirtual
和invokespecial
都采用2个参数,因此下一个操作码将在3个字节后找到。在这两种情况下,需要参数(indexbyte1和indexbyte2)来计算常量池中的位置(indexbyte1 << 8) | indexbyte2)
Javap为您查找这些值,这是实际指令后评论中的引用。
答案 1 :(得分:0)
那些不是指令编号,它们是指令相对于方法的字节偏移量。
我仍在寻找官方文档,但this link确认了这一点。