jvm_字节码的基本信息

字节码文件基本组成部分解析 。字节码文件中的十六进制数据中
每两个文字符号为一个字节。

1. 魔数

在字节码文件中,魔数占据了4个字节
在我们以上的字节码数据中,从0开始数4个字节就是我们的魔数,
java语言中,魔数固定为 【 CAFEBABE 】

2. 版本号

魔数后的4个字节为版本号,主次版本号分别占据2个字节 ,
十六进制数据 : 00000033 -> jdk版本为 51

3. 常量池

版本号后面 2个字节为常量池大小的定义: 0019 -> 25 
可以看到常量池的大小为24 (25-1)
索引0 为保留常量 null,不位于常量表中

3.1 常量池表分析

根据下面的常量池表进行分析: 

我们得到常量池分析的结束位置: 

4. AccessFlag访问标志

常量池结束 accessflag占据2个字节 : 0021 
这个表里面无法直接查询到0021这个值,原因是0021=0020+0001,也就是表示当前class的access_flag是ACC_PUBLIC|ACC_SUPER
参考下表:

5. ClassName 类名

访问标识后面2个字节: 0003 说明类名在常量池表中的索引为 3 

6. SuperClassName 父类名

类名后占据2个字节: 0004 ,在常量池的索引为4

7. 接口 interface名

父类后占据2个字节: 0000 因为我们的类,没有实现接口所以为0 

8. fields

占据2个字节: 0001  数量为1 

8.1 字段表结构

每个成员变量对应一个field_info结构:
field_info {
                     u2 access_flags; 0002
                     u2 name_index; 0005
                     u2 descriptor_index; 0006
                     u2 attributes_count; 0000
                     attribute_info attributes[attributes_count];
           }
 access_flags为0002,即是ACC_PRIVATE
name_index指向常量池的第五个常量,为“test”
descriptor_index指向常量池的第6个常量为“I”
三个字段结合起来,说明这个变量是"private int test"。
接下来的是attribute字段,用来描述该变量的属性,因为这个变量没有附加属性,所以attributes_count为	0,attribute_info为空。

9. methods

占据2个字节: 0004

9.1 方法表结构

method_info {
                     u2 access_flags;
                     u2 name_index;
                     u2 descriptor_index;
                     u2 attributes_count;
                     attribute_info  attributes[attributes_count];
                }
             

9.2 0009 code 结构表

Code_attribute {
      u2 attribute_name_index;
      u4 attribute_length;
      u2 max_stack;
      u2 max_locals;
      u4 code_length;
      u1 code[code_length];
      u2 exception_table_length;
      { 
           u2 start_pc;
           u2 end_pc;
           u2 handler_pc;
           u2 catch_type;
      } exception_table[exception_table_length];
      u2 attributes_count;
      attribute_info attributes[attributes_count];
 }
 
attribute_length表示attribute所包含的字节数,这里为0000001d,即是39个字节,不包含	attribute_name_index和attribute_length字段。
max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度,这里是0001
max_locals表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量,这里是0001.
接下来的code_length表示该方法的所包含的字节码的字节数以及具体的指令码。
这里的字节码长度为00000005,即是后面的5个字节 2a b7 00 01 b1为对应的字节码指令的指令码。
参照下表可以将上面的指令码翻译成对应的助记符:

9.3 属性表结构

attribute_info {
                     u2 attribute_name_index;
                     u4 attribute_length;
                     u1 info[attribute_length];
                }