简体   繁体   English

读取Java字节码指令:数字是什么意思?

[英]Reading a Java bytecode instruction: What does the number mean?

I was reading java bytecode and saw this: 我正在阅读java字节码,看到了这个:

getfield #5 (Field java.lang.String name)

What does #5 mean? #5是什么意思?

And how can I write a program in bytecode? 我怎样才能用字节码编写程序?

Java class files and bytecode Java类文件和字节码

Java class files (bytecode-files) is composed by different components: Java类文件(字节码文件)由不同的组件组成:

http://en.wikipedia.org/wiki/Java_class_file http://en.wikipedia.org/wiki/Java_class_file

  • Magic Number: 0xCAFEBABE 幻数:0xCAFEBABE
  • Version of Class File Format: the minor and major versions of the class file 类文件格式的版本:类文件的次要版本和主要版本
  • Constant Pool: Pool of constants for the class 常量池:类的常量池
  • (...) (......)
  • Fields: Any fields in the class 字段:类中的任何字段
  • Methods: Any methods in the class 方法:类中的任何方法
  • Attributes: Any attributes of the class (for example the name of the sourcefile, etc.) 属性:类的任何属性(例如源文件的名称等)

The number #5 simply refers to a location in the constant pool. 数字#5仅指恒定池中的位置。 And in that position a CONSTANT_FieldRef is found which contains a reference to a CONSTANT_NameAndType among other attributes. 在该位置找到CONSTANT_FieldRef,其中包含对CONSTANT_NameAndType以及其他属性的引用。 And CONSTANT_NameAndType contains a reference to a CONSTANT_Utf8 (which contains the actual string/name.) CONSTANT_NameAndType包含对CONSTANT_Utf8的引用(包含实际的字符串/名称。)

So the flow looks like this: 所以流程看起来像这样:

getfield #number -> FieldRef -> NameAndType -> Utf8 -> string

http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

So instead of saving a whole string in each getfield instruction a number is saved. 因此,不是在每个getfield指令中保存整个字符串,而是保存一个数字。 This improves performance in the interpreter (or JIT) and space in the class file. 这提高了类文件中解释器(或JIT)和空间的性能。

Hand-write bytecodes 手写字节码

Hand-written bytecodes can be assembled to a class file with this tool (it contains a lot of examples): 可以使用此工具将手写字节码组装到类文件中(它包含大量示例):

http://jasmin.sourceforge.net/ http://jasmin.sourceforge.net/

The getfield instruction (IIRC) makes a reference into the class file's constant pool for information about what field should be looked up. getfield指令(IIRC)引用类文件的常量池,以获取有关应查找哪个字段的信息。 The #5 here means "constant pool entry number 5," and this constant pool then contains information saying "look up the field name of type java.lang.String ). The reason for this is that it keeps the size of the getfield instruction the same, regardless of the name or type of the field to look up. 这里的#5表示“常量池条目号5”,然后这个常量池包含“查找java.lang.String类型的字段name ”的信息。原因是它保留了getfield指令的大小同样,无论要查找的字段的名称或类型如何。

I'm not sure I understand what you mean by "how can I write program in bytecode?" 我不确定我是什么意思“我怎么能用字节码编写程序?” This is a pretty open-ended question; 这是一个非常开放的问题; it's akin to asking how to write programs in any language, and requires a lot of learning. 它类似于询问如何用任何语言编写程序,并且需要大量的学习。 You may want to look into the Jasmin Java assembler, which can greatly simplify this process. 您可能需要查看Jasmin Java汇编程序,它可以大大简化此过程。

Hope this helps! 希望这可以帮助!

it's constant pool index, constant pool stores all the info of class file, JVM instruction use index to reference class info like fields, methods. 它是常量池索引,常量池存储类文件的所有信息,JVM指令使用索引来引用类信息,如字段,方法。

I will use hello world example to show how it works: 我将使用hello world示例来展示它是如何工作的:

source : 来源

System.out.println("hello world");

bytecode 字节码

 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

bytecode instruction is formatted as instruction constant pool index 字节码指令被格式化为instruction constant pool index

  Constant pool:

   #4 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #28 = Class              #36            // java/io/PrintStream
  #29 = NameAndType        #37:#38        // println:(Ljava/lang/String;)V
  #36 = Utf8               java/io/PrintStream
  #37 = Utf8               println
  #38 = Utf8               (Ljava/lang/String;)V

so this instruction will call a method with index 4 所以这条指令将调用索引为4的方法

invokevirtual #4

and index 4 is a Methodref of // java/io/PrintStream.println:(Ljava/lang/String;)V 和index 4是// java/io/PrintStream.println:(Ljava/lang/String;)VMethodref // java/io/PrintStream.println:(Ljava/lang/String;)V

if we follow the reference in the constant pool, we will find all the information is stored in string and composted to complex type like method, filed, class. 如果我们遵循常量池中的引用,我们将发现所有信息都存储在字符串中并堆叠成复杂类型,如方法,字段,类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM