如何手动读取java字节码仅用于理解目的?

时间:2013-12-18 19:47:34

标签: java bytecode .class-file

我正在阅读此wiki article有关如何将某些代码转换为Java bytecode的信息。 我遇到了这个例子:

Consider the following Java code:

  outer:
  for (int i = 2; i < 1000; i++) {
      for (int j = 2; j < i; j++) {
          if (i % j == 0)
              continue outer;
      }
      System.out.println (i);
  }

A Java compiler might translate the Java code above into byte code as follows, 
assuming the above was put in a method:

  0:   iconst_2
  1:   istore_1
  2:   iload_1
  3:   sipush  1000
  6:   if_icmpge       44
  9:   iconst_2
  10:  istore_2
  11:  iload_2
  12:  iload_1
  13:  if_icmpge       31
  16:  iload_1
  17:  iload_2
  18:  irem
  19:  ifne    25
  22:  goto    38
  25:  iinc    2, 1
  28:  goto    11
  31:  getstatic       #84; //Field java/lang/System.out:Ljava/io/PrintStream;
  34:  iload_1
  35:  invokevirtual   #85; //Method java/io/PrintStream.println:(I)V
  38:  iinc    1, 1
  41:  goto    2
  44:  return
  1. 我不理解bytecode.的一行,如果不是全部,我想了解它的某些部分。或者其中一些行是什么意思,例如iconst_2
  2. bytecode.class个文件相同或.class个文件包含bytecode?。下图显示.classbytecode相同
  3. 如果它们不同,bytecode如何从.class文件中提取JVM
  4. SO中的一些帖子一般会谈到bytecode,但我没有看到任何帖子解释classbytecode之间的关系(如果有的话)以及如何阅读{{ 1}}内容作为用户(而不是JVM)。enter image description here

3 个答案:

答案 0 :(得分:4)

有时我发现有一种假设,当它不是时,它必须非常复杂。它实际上很简单。

  

我不理解字节码的单行。如果不是全部,我想了解它的某些部分。或者其中一些行是什么意思,比如iconst_2?

iconst_2代表整数常量2

  

是字节码和.class文件相同还是.class文件包含字节码?

.class包含多个字节代码。它还包含一些常数,例如字符串文字和大型基元。但是,您可以将它们视为同一个。

  

下图显示.class和字节码相同

该图是简化视图。简单来说,它们是一回事。

  

如果它们不同,JVM如何从.class文件中提取字节码?

.class有specific format如果您遵循该格式,您将找到字节代码。正如您所看到的,文件中不仅包含字节代码,而且字节代码是您应该关注的唯一位。 (实际上你不应该在99%的情况下真正关心字节码)

从上面链接的类文件格式。

  

一个类文件由一个ClassFile结构组成:

ClassFile {
    u4 magic;
    u2 minor_version;
    u2 major_version;
    u2 constant_pool_count;
    cp_info constant_pool[constant_pool_count-1];
    u2 access_flags;
    u2 this_class;
    u2 super_class;
    u2 interfaces_count;
    u2 interfaces[interfaces_count];
    u2 fields_count;
    field_info fields[fields_count];
    u2 methods_count;
    method_info methods[methods_count];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}

答案 1 :(得分:1)

了解字节码和类文件格式的最佳方法是只读取JVM规范。它是免费在线提供的,并不难理解(你可以跳过所有的Prolog垃圾)。这就是我开始的方式。在那之后,这只是一个练习和探索的问题。您可以通过编译和分解各种类来了解它在实践中的用法。

从技术上讲,字节码只是指代代码属性中的实际指令,但如果没有其他的类文件,它几乎没有意义,所以通常当我说字节码时,我指的是整个类文件格式。

我还从Krakatau汇编程序中编写字节码的角度编写了一个字节码教程。不幸的是,它并没有走得太远,因为我因为缺乏兴趣而停止写作,但它可能仍然有用。你可以找到它here

答案 2 :(得分:0)

我可以推荐一本书“计算机组成和汇编语言原理”:

  

今天的新生更有可能接触到Java而不是   以往。专注于现代架构(Java Virtual   机器,或JVM),本文提供了彻底的处理   在今天的便携式环境中的计算机组织原则   电脑。为学生提供简单但实际的例子   完全理解计算如何在这样的机器上工作。   Juola使这种材料在经常的课程中有用且相关   二年级的CS学生很难。