java字节码表
java源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class TestByteCode { public static void test() { int a = 10; int b = 10; int c = (a+b)*10; System.out.println(c); } public static void main(String[] args) { // TODO Auto-generated method stub String s = new String("aaaa"); test(); } }
编译出的class通过javap -c TestByteCode.class解析出的字节码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72public class com.learn.test.code.bytecode.TestByteCode { public com.learn.test.code.bytecode.TestByteCode(); /*这段是构造函数*/ Code: /*加载了操作数栈中栈顶的引用*/ 0: aload_0 /*invokespecial指的是调用父类的构造方法,完成实例初始化,#1是构造方法地址,应该指向方法区*/ 1: invokespecial #1 // Method java/lang/Object."<init>":()V /*返回空,如果是ireturn就是返回int,areturn返回引用,lreturn返回long型*/ 4: return /*test方法部分字节码*/ public static void test(); Code: 0: bipush 10 /*把int型的10push到操作树栈栈顶*/ 2: istore_0 /*把栈顶的10出栈存放到局部变量表中的0号变量*/ 3: bipush 10 /*把int型的10push到操作树栈栈顶*/ 5: istore_1 /*把栈顶的int型的10出栈存放到局部变量表中的0号变量*/ 6: iload_0 /*加载int型的0号局部标量到栈顶*/ 7: iload_1 /*加载int型的1号局部标量到栈顶*/ 8: iadd /*把栈顶的两元素弹出并相加放到栈顶*/ 9: bipush 10 /*把int型的10压到栈顶*/ 11: imul /*把栈顶的两元素弹出并相乘放到栈顶*/ 12: istore_2 /*把栈顶的int型数据出栈存放到局部变量表中的2号变量*/ /*getStatic获得指定类的静态域,并将值压如栈顶,#2为地址*/ 13: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 16: iload_2 /*把局部变量表中的2号变量加载到栈顶*/ /*invokevitual 调用实例方法*/ 17: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 20: return /*返回空*/ public static void main(java.lang.String[]); Code: 0: new #4 // class java/lang/String /*创建一个对象并压入栈顶*/ 3: dup /*复制栈顶数值并将复制值压入栈顶*/ 4: ldc #5 // String aaaa /*将 int, float 或 String 型常量值从常量池中推送至栈顶*/ /*invokespecial调用构造函数,调用String的构造函数*/ 6: invokespecial #6 // Method java/lang/String."<init>":(Ljava/lang/String;)V 9: astore_1 /*把引用存放到当前栈帧的1号局部变量*/ 10: invokestatic #7 // Method test:()V /*调用静态方法*/ 13: return }
常用的Java字节码指令有:
-
加载到操作数栈
bipush 加载常量到操作数栈顶
iload 将int型局部变量加载到栈顶
lload 将long型局部变量加载到栈顶
iconst_0 将int型0加载到栈顶
fconst_0 将float型加载到栈顶
ldc 加载常量池中数据到栈中 -
存储
istore 将栈顶int出栈并存放到局部变量中
fstore 将栈顶float出栈并存放到局部变量中 -
计算
iadd ladd fadd dadd 栈顶两操作数操作,int或long等,结果压栈顶
isub lsub fsub dsub 减法
imul lmul fmul 乘法
idiv ldiv fdiv 除法
irem lrem 取模
ineg lneg 取非
ishl 左位移
ifeq ifne 比较 -
调用相关
getstatic 获取指定类的静态域,并入栈
invokespecial 调用超类构造方法,实例初始化方法,私有方法。
invokestatic 调用静态方法。
“invokeinterface” 调用接口方法。
invokedynamic 调用动态链接方法 -
内存分配
new 创建一个对象,并将其引用值压入栈顶。
newarray 创建一个指定原始类型(如 int、 float、 char??)的数组,并将其引用值压入栈顶 -
返回
ireturn 从当前方法返回 int。
lreturn 从当前方法返回 long。
freturn 从当前方法返回 float。
有了这些基本能读懂些字节码了
最后
以上就是寒冷蓝天最近收集整理的关于java字节码解析学习的全部内容,更多相关java字节码解析学习内容请搜索靠谱客的其他文章。
发表评论 取消回复