如何读取反汇编的 Java 字节码产生的助记符的元数据?
How to read the metadata for the mnemonics produced by disassembled Java Bytecode?
我以前从未使用过 Javap。有人可以解释一下 "Code" 在此示例中的含义吗?它出现了三分之二的时间。在它下面几行后面的助记符的上下文中,它是什么意思?是不是说明还有一个Stack frame什么的?:
Compiled from "DocFooter.java"
public class DocFooter extends java.applet.Applet {
java.lang.String date;
java.lang.String email;
public DocFooter();
Code:
0: aload_0
1: invokespecial #1 // Method java/applet/Applet."<init>":()V
4: return
public void init();
Code:
0: aload_0
1: sipush 500
4: bipush 100
6: invokevirtual #2 // Method resize:(II)V
9: aload_0
10: aload_0
11: ldc #3 // String LAST_UPDATED
13: invokevirtual #4 // Method getParameter:(Ljava/lang/String;)Ljava/lang/String;
16: putfield #5 // Field date:Ljava/lang/String;
19: aload_0
20: aload_0
21: ldc #6 // String EMAIL
23: invokevirtual #4 // Method getParameter:(Ljava/lang/String;)Ljava/lang/String;
26: putfield #7 // Field email:Ljava/lang/String;
29: return
public void paint(java.awt.Graphics);
Code:
0: aload_1
1: new #8 // class java/lang/StringBuilder
4: dup
5: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
8: aload_0
9: getfield #5 // Field date:Ljava/lang/String;
12: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: ldc #11 // String by
17: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: bipush 100
25: bipush 15
27: invokevirtual #13 // Method java/awt/Graphics.drawString:(Ljava/lang/String;II)V
30: aload_1
31: aload_0
32: getfield #7 // Field email:Ljava/lang/String;
35: sipush 290
38: bipush 15
40: invokevirtual #13 // Method java/awt/Graphics.drawString:(Ljava/lang/String;II)V
43: return
}
我查看了 JVM 的规范,但没有找到任何解释 "Code:",但如果事实证明我忽略了它,我很高兴 post link 那部分.谢谢
Javap 是一种旨在帮助 Java 程序员调试代码的工具。它不是为工具使用而设计的,也没有正式的输出规范。它可以而且确实会随着版本的不同而变化。
也就是说,如果您了解 JVM 规范和 class 文件格式,就很容易理解 Javap 的输出。
另请注意,Javap 试图让事情变得更像 Java,这会隐藏或模糊字节码的一些细节。例如,它输出 Java 风格的方法签名,这不一定反映字节码中的内容(并且它隐藏了合成参数)。
如果你想看到更接近字节码的东西,但仍然是人类可读的,我推荐 Krakatau disassembler(披露,我写的)。还有很多其他查看字节码的工具,它们几乎都比 Javap 好(不难比 Javap 好)。
Furthermore, what are the line numbers (0:),
行号只是该指令在字节码中的偏移量。它从 0 开始,大多数指令是 1 或 3 个字节。有关详细信息,请参阅 JVM 规范。
what do the different sections mean (Public void init() followed by Code: on the next line), and what do the #[number] and comments mean?
显示 class 中的每个方法,带有 Javap-mangled Java 风格的方法签名。然后是该方法字节码中每条指令的文本表示。同样,请参阅 JVM 规范了解详细信息。
Java Virtual Machine Spec 页面是一个链接的迷宫,所以,请允许我指出在何处可以找到有关反汇编字节码的信息。大多数关于反汇编字节码的内容都可以在 3 下找到。为 Java 虚拟机 编译。此外,可以在这里 Format of Examples.
找到我的问题的直接答案
另外,Antimony 的回答让我们更深入地了解其他查看字节码的替代方法。
我以前从未使用过 Javap。有人可以解释一下 "Code" 在此示例中的含义吗?它出现了三分之二的时间。在它下面几行后面的助记符的上下文中,它是什么意思?是不是说明还有一个Stack frame什么的?:
Compiled from "DocFooter.java"
public class DocFooter extends java.applet.Applet {
java.lang.String date;
java.lang.String email;
public DocFooter();
Code:
0: aload_0
1: invokespecial #1 // Method java/applet/Applet."<init>":()V
4: return
public void init();
Code:
0: aload_0
1: sipush 500
4: bipush 100
6: invokevirtual #2 // Method resize:(II)V
9: aload_0
10: aload_0
11: ldc #3 // String LAST_UPDATED
13: invokevirtual #4 // Method getParameter:(Ljava/lang/String;)Ljava/lang/String;
16: putfield #5 // Field date:Ljava/lang/String;
19: aload_0
20: aload_0
21: ldc #6 // String EMAIL
23: invokevirtual #4 // Method getParameter:(Ljava/lang/String;)Ljava/lang/String;
26: putfield #7 // Field email:Ljava/lang/String;
29: return
public void paint(java.awt.Graphics);
Code:
0: aload_1
1: new #8 // class java/lang/StringBuilder
4: dup
5: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
8: aload_0
9: getfield #5 // Field date:Ljava/lang/String;
12: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: ldc #11 // String by
17: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: bipush 100
25: bipush 15
27: invokevirtual #13 // Method java/awt/Graphics.drawString:(Ljava/lang/String;II)V
30: aload_1
31: aload_0
32: getfield #7 // Field email:Ljava/lang/String;
35: sipush 290
38: bipush 15
40: invokevirtual #13 // Method java/awt/Graphics.drawString:(Ljava/lang/String;II)V
43: return
}
我查看了 JVM 的规范,但没有找到任何解释 "Code:",但如果事实证明我忽略了它,我很高兴 post link 那部分.谢谢
Javap 是一种旨在帮助 Java 程序员调试代码的工具。它不是为工具使用而设计的,也没有正式的输出规范。它可以而且确实会随着版本的不同而变化。
也就是说,如果您了解 JVM 规范和 class 文件格式,就很容易理解 Javap 的输出。
另请注意,Javap 试图让事情变得更像 Java,这会隐藏或模糊字节码的一些细节。例如,它输出 Java 风格的方法签名,这不一定反映字节码中的内容(并且它隐藏了合成参数)。
如果你想看到更接近字节码的东西,但仍然是人类可读的,我推荐 Krakatau disassembler(披露,我写的)。还有很多其他查看字节码的工具,它们几乎都比 Javap 好(不难比 Javap 好)。
Furthermore, what are the line numbers (0:),
行号只是该指令在字节码中的偏移量。它从 0 开始,大多数指令是 1 或 3 个字节。有关详细信息,请参阅 JVM 规范。
what do the different sections mean (Public void init() followed by Code: on the next line), and what do the #[number] and comments mean?
显示 class 中的每个方法,带有 Javap-mangled Java 风格的方法签名。然后是该方法字节码中每条指令的文本表示。同样,请参阅 JVM 规范了解详细信息。
Java Virtual Machine Spec 页面是一个链接的迷宫,所以,请允许我指出在何处可以找到有关反汇编字节码的信息。大多数关于反汇编字节码的内容都可以在 3 下找到。为 Java 虚拟机 编译。此外,可以在这里 Format of Examples.
找到我的问题的直接答案另外,Antimony 的回答让我们更深入地了解其他查看字节码的替代方法。