(java) Hello world 程序的字节码分析(尚未完成

2019-12-04  本文已影响0人  jyjz2008

参考文献

  1. class 文件格式: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
  2. od 命令
  3. javap 命令

Hello.java

Hello.java 文件的内容如下

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}

Hello.java 被编译成 Hello.class 后,可以被虚拟机执行。
class 文件有自己的格式,细节可以参考 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
由于 Hello.java 的内容比较简单,所以我就以 Hello.class 的内容为例,来简单解释一下 class 文件的格式。

Hello.class

借助如下命令,我们可以将 Hello.java 编译成 Hello.class

javac Hello.java

借助如下命令,我们可以查看 Hello.class 文件的内容

od -t x1 Hello.class

上述命令的完整输出结果如下

0000000    ca  fe  ba  be  00  00  00  34  00  1d  0a  00  06  00  0f  09
0000020    00  10  00  11  08  00  12  0a  00  13  00  14  07  00  15  07
0000040    00  16  01  00  06  3c  69  6e  69  74  3e  01  00  03  28  29
0000060    56  01  00  04  43  6f  64  65  01  00  0f  4c  69  6e  65  4e
0000100    75  6d  62  65  72  54  61  62  6c  65  01  00  04  6d  61  69
0000120    6e  01  00  16  28  5b  4c  6a  61  76  61  2f  6c  61  6e  67
0000140    2f  53  74  72  69  6e  67  3b  29  56  01  00  0a  53  6f  75
0000160    72  63  65  46  69  6c  65  01  00  0a  48  65  6c  6c  6f  2e
0000200    6a  61  76  61  0c  00  07  00  08  07  00  17  0c  00  18  00
0000220    19  01  00  0b  48  65  6c  6c  6f  20  77  6f  72  6c  64  07
0000240    00  1a  0c  00  1b  00  1c  01  00  05  48  65  6c  6c  6f  01
0000260    00  10  6a  61  76  61  2f  6c  61  6e  67  2f  4f  62  6a  65
0000300    63  74  01  00  10  6a  61  76  61  2f  6c  61  6e  67  2f  53
0000320    79  73  74  65  6d  01  00  03  6f  75  74  01  00  15  4c  6a
0000340    61  76  61  2f  69  6f  2f  50  72  69  6e  74  53  74  72  65
0000360    61  6d  3b  01  00  13  6a  61  76  61  2f  69  6f  2f  50  72
0000400    69  6e  74  53  74  72  65  61  6d  01  00  07  70  72  69  6e
0000420    74  6c  6e  01  00  15  28  4c  6a  61  76  61  2f  6c  61  6e
0000440    67  2f  53  74  72  69  6e  67  3b  29  56  00  21  00  05  00
0000460    06  00  00  00  00  00  02  00  01  00  07  00  08  00  01  00
0000500    09  00  00  00  1d  00  01  00  01  00  00  00  05  2a  b7  00
0000520    01  b1  00  00  00  01  00  0a  00  00  00  06  00  01  00  00
0000540    00  01  00  09  00  0b  00  0c  00  01  00  09  00  00  00  25
0000560    00  02  00  01  00  00  00  09  b2  00  02  12  03  b6  00  04
0000600    b1  00  00  00  01  00  0a  00  00  00  0a  00  02  00  00  00
0000620    03  00  08  00  04  00  01  00  0d  00  00  00  02  00  0e    
0000637

class 文件的内容可以分为如下几部分

名称 参考译名 长度(单位:字节)
magic 魔数 4
minor_version 次版本号 2
major_version 主版本号 2
constant_pool_count 常量池大小? 2
constant_pool 常量池 不固定
access_flags 访问标志 2
this_class 类索引 2
super_class 父类索引 2
interfaces_count 接口数量 2
interfaces ? interfaces_count * 2
fields_count 2
fields 不固定
methods_count 2
methods 不固定
attributes_count 2
attributes 不固定

下面我们来逐个分析

magic(魔数)

前四个字节的值为 0xCAFEBABE

image.png

minor_version(次版本号)

Hello.class 中的次版本号为 0

image.png

major_version(主版本号)

Hello.class 中的主版本号为十进制的 52(如果写成十六进制,就是 0x34)

image.png

constant_pool_count

值为 0x1d(用十进制表示29)

image.png

constant_pool(常量池)

#1

常量池中的 #1 元素共有5个字节,即 0x0a0006000f

image.png
第一个字节为 0x0a 表示 CONSTANT_Methodref
其结构为
CONSTANT_Methodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}

具体值如下

tag=0x0a
class_index=0x0006
name_and_type_index=0x000f
上一篇 下一篇

猜你喜欢

热点阅读