java字节码基本指令_JVM | 字节码指令基础

操作数栈管理指令

1)pop、pop2:将操作数栈的栈顶一个或两个元素出栈。

2)dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2:复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶。

3)swap:将栈最顶端两个数值互换。

public static void main(String[] args) {

heavyMethod();

}

对应的字节码:

public static void main(java.lang.String[]);

Signature: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=1, locals=1, args_size=1

0: invokestatic #23 // Method heavyMethod:()I

3: pop

4: return

LineNumberTable:

line 115: 0

line 116: 4

加载、存储指令

1)iload、iload、lload、lload、fload、fload、dload、dload、aload、aload:将一个局部变量加载到操作数栈。

2)istore、istore、lstore、lstore、fstore、fstore、dstore、dstore、astore、astore:将一个数值从操作数栈存储到局部变量表。

3)bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconstm1、iconst、lconst、fconst、dconst_:将一个常量加载到操作数栈。

4)wide:扩充局部变量表的访问索引的指令。

public static int methodE(){

int e = 100;

int c = 300;

int d = 300000;

e++;

++e;

--e;

e--;

return c + d + e;

}

对应的字节码:

public static int methodE();

Signature: ()I

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=3, args_size=0

0: bipush 100

2: istore_0

3: sipush 300

6: istore_1

7: ldc #5 // int 300000

9: istore_2

10: iinc 0, 1

13: iinc 0, 1

16: iinc 0, -1

19: iinc 0, -1

22: iload_1

23: iload_2

24: iadd

25: iload_0

26: iadd

27: ireturn

LineNumberTable:

line 40: 0

line 41: 3

line 42: 7

line 43: 10

line 44: 13

line 45: 16

line 46: 19

line 47: 22

运算指令

1)iadd、ladd、fadd、dadd:加法指令。

2)isub、lsub、fsub、dsub:减法指令。

3)imul、lmul、fmul、dmul:乘法指令。

4)idiv、ldiv、fdiv、ddiv:除法指令。

5)irem、lrem、frem、drem:求余指令。

6)ineg、lneg、fneg、dneg:取反指令。

7)ishl、ishr、iushr、lshl、lshr、lushr:位移指令。

8)ior、lor:按位或指令。

9)iand、land:按位与指令。

10)ixor、lxor:按位异或指令。

11)iinc:局部变量自增指令。

12)dcmpg、dcmpl、fcmpg、fcmpl、lcmp:比较指令。

参照上例。

类型转换指令

1)int类型到long、float或者double类型,long类型到float、double类型,float类型到double类型:宽化类型转换(虚拟机直接支持)。

2)i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f:窄化类型转换(显式指令)。

public static void methodK(){

int i = 97;

short i2s = (short) i;

char i2c = (char) i;

long i2l = i;

float i2f = i;

double i2d = i;

float l2f = i2l;

double l2d = i2l;

}

对应的字节码:

public static void methodK();

Signature: ()V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=11, args_size=0

0: bipush 97

2: istore_0

3: iload_0

4: i2s

5: istore_1

6: iload_0

7: i2c

8: istore_2

9: iload_0

10: i2l

11: lstore_3

12: iload_0

13: i2f

14: fstore 5

16: iload_0

17: i2d

18: dstore 6

20: lload_3

21: l2f

22: fstore 8

24: lload_3

25: l2d

26: dstore 9

28: return

LineNumberTable:

line 100: 0

line 101: 3

line 102: 6

line 103: 9

line 104: 12

line 105: 16

line 106: 20

line 107: 24

line 108: 28

对象创建与访问指令

1)new :创建类实例的指令。

2)newarray、anewarray、multianewarray:创建数组的指令。

3)getstatic、putstatic、getfield、putfield:访问类字段(类变量)和实例字段(实例变量)的指令。

4)baload、caload、saload、iaload、laload、faload、daload、aaload:把一个数组元素加载到操作数栈的指令。

5)bastore、castore、sastore、iastore、lastore、fastore、dastore、aastore:把一个操作数栈的值存储到数组元素中的指令。

6)arraylength:取数组长度的指令。

7)instanceof、checkcast:检查类实例类型的指令。

public static void methodJ(){

new SimpleMethodExecuteProcess();

System.out.println(SimpleMethodExecuteProcess.i);

}

对应的字节码:

public static void methodJ();

Signature: ()V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=0, args_size=0

0: new #9 // class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess

3: dup

4: invokespecial #10 // Method "":()V

7: pop

8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

11: getstatic #11 // Field i:I

14: invokevirtual #12 // Method java/io/PrintStream.println:(I)V

17: return

LineNumberTable:

line 91: 0

line 93: 8

line 94: 17

控制转移指令

1)ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull、if_icmpeq、if_icmpne、if_icmplt、if_icmpgt、if_icmple、if_icmpge、if_acmpeq、if_acmpne:条件分支。

2)tableswitch、lookupswitch:复合条件分支。

3)goto、goto_w、jsr、jsr_w、ret:无条件分支。

public static void methodG(){

if(i == 0){

System.out.println(System.currentTimeMillis());

}

while(i < 1){

System.out.println(System.currentTimeMillis());

i++;

}

}

对应的字节码:

public static void methodG();

Signature: ()V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=3, locals=0, args_size=0

0: getstatic #6 // Field i:I

3: ifne 15

6: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

9: invokestatic #7 // Method java/lang/System.currentTimeMillis:()J

12: invokevirtual #8 // Method java/io/PrintStream.println:(J)V

15: getstatic #6 // Field i:I

18: iconst_1

19: if_icmpge 42

22: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

25: invokestatic #7 // Method java/lang/System.currentTimeMillis:()J

28: invokevirtual #8 // Method java/io/PrintStream.println:(J)V

31: getstatic #6 // Field i:I

34: iconst_1

35: iadd

36: putstatic #6 // Field i:I

39: goto 15

42: return

LineNumberTable:

line 62: 0

line 63: 6

line 66: 15

line 67: 22

line 68: 31

line 70: 42

StackMapTable: number_of_entries = 2

frame_type = 15 /* same */

frame_type = 26 /* same */

异常处理指令

athrow :显式抛出异常指令。

public static void methodH(){

try {

throw new NullPointerException("nothing ...");

// do nothing ...

} catch (Throwable t){

// do nothing ...

}

}

对应的字节码:

public static void methodH();

Signature: ()V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=3, locals=1, args_size=0

0: new #9 // class java/lang/NullPointerException

3: dup

4: ldc #10 // String nothing ...

6: invokespecial #11 // Method java/lang/NullPointerException."":(Ljava/lang/String;)V

9: athrow

10: astore_0

11: return

Exception table:

from to target type

0 10 10 Class java/lang/Throwable

LineNumberTable:

line 77: 0

line 79: 10

line 82: 11

StackMapTable: number_of_entries = 1

frame_type = 74 /* same_locals_1_stack_item */

stack = [ class java/lang/Throwable ]

同步指令

monitorenter、monitorexit:支持synchronized语句块语义的指令。

public void methodI(){

synchronized (Integer.class){

// do nothing ...

}

}

对应的字节码:

public void methodI();

Signature: ()V

flags: ACC_PUBLIC

Code:

stack=2, locals=3, args_size=1

0: ldc_w #13 // class java/lang/Integer

3: dup

4: astore_1

5: monitorenter

6: aload_1

7: monitorexit

8: goto 16

11: astore_2

12: aload_1

13: monitorexit

14: aload_2

15: athrow

16: return

Exception table:

from to target type

6 8 11 any

11 14 11 any

LineNumberTable:

line 88: 0

line 90: 6

line 91: 16

StackMapTable: number_of_entries = 2

frame_type = 255 /* full_frame */

offset_delta = 11

locals = [ class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess, class java/lang/Object ]

stack = [ class java/lang/Throwable ]

frame_type = 250 /* chop */

offset_delta = 4

synchronized 修饰方法的语义解析:可以直接从方法常量池的方法表结构中ACC_SYNCHRONIZED访问标志得知一个方法是否声明为同步方法,不需要解析出monitorenter、monitorexit同步指令。

public static synchronized void methodL(){

int i = 97;

}

public static synchronized void methodL();

Signature: ()V

flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED

Code:

stack=1, locals=1, args_size=0

0: bipush 97

2: istore_0

3: return

LineNumberTable:

line 120: 0

line 121: 3

方法调用和返回指令

1)invokestatic:调用静态方法。

2)invokespecial:调用实例构造器方法、私有方法和父类方法。

3)invokevirtual:调用所有的虚方法。非虚方法以外的都是虚方法,非虚方法包括使用invokestatic、invokespecial调用的方法和被final修饰的方法。

4)invokeinterface:调用接口方法,运行时再确定一个实现此接口的对象。

5)invokedynamic:用于在运行时动态解析出调用点限定符所引用的方法,并执行该方法。

ireturn(返回值是boolean、byte、char、short、int)、lreturn、freturn、dreturn、areturn:方法返回指令。

public static int heavyMethod(){

int a = 200;

int b = 100;

int c = methodC(methodA(methodA(a, b), b), methodB(a, b));

methodD();

methodE();

methodF();

methodG();

methodH();

new SimpleMethodExecuteProcess().methodI();

methodJ();

methodK();

methodL();

return c;

}

对应的字节码:

public static int heavyMethod();

Signature: ()I

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=3, locals=3, args_size=0

0: sipush 200

3: istore_0

4: bipush 100

6: istore_1

7: iload_0

8: iload_1

9: invokestatic #17 // Method methodA:(II)I

12: iload_1

13: invokestatic #17 // Method methodA:(II)I

16: iload_0

17: iload_1

18: invokestatic #18 // Method methodB:(II)I

21: invokestatic #19 // Method methodC:(II)I

24: istore_2

25: invokestatic #20 // Method methodD:()V

28: invokestatic #21 // Method methodE:()I

31: pop

32: invokestatic #22 // Method methodF:()D

35: pop2

36: invokestatic #23 // Method methodG:()V

39: invokestatic #24 // Method methodH:()V

42: new #14 // class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess

45: dup

46: invokespecial #15 // Method "":()V

49: invokevirtual #25 // Method methodI:()V

52: invokestatic #26 // Method methodJ:()V

55: invokestatic #27 // Method methodK:()V

58: invokestatic #28 // Method methodL:()V

61: iload_2

62: ireturn

LineNumberTable:

line 128: 0

line 129: 4

line 130: 7

line 131: 25

line 132: 28

line 133: 32

line 134: 36

line 135: 39

line 136: 42

line 137: 52

line 138: 55

line 139: 58

line 140: 61

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值