字节码指令速查

195 阅读2分钟

《ASM4 使用指南》 - A. 附录

同时参考:docs.oracle.com/javase/spec…

A.1 字节码指令

本节对字节码指令进行简要描述 。如需全面描述, 请参阅 Java 虚拟机规范。

约定:

  • a 和 b 表示 int, float, long 或 double 值 (比如, 它们对于 IADD 表示 int, 而 对于 LADD 则表示 long) ,
  • o 和 p 表示对象引用,
  • v 表示任意值 (或者,对于栈指令, 表示大小为1的值) ,
  • w 表示 long 或 double,
  • i、j 和 n 表示 int 值。

局部变量

指令之前的栈之后的栈
ILOAD , LLOAD , FLOAD ,DLOAD var. . .. . . , a
ALOAD var, o
ISTORE , LSTORE , FSTORE , DSTORE var. . . , a. . .
ASTORE var. . . , o. . .
IINC var incr. . . , a. . . , a + incr

栈操作

指令之前的栈之后的栈
POP. . . , v. . .
POP2. . . , v1 , v2. . .
. . . , w. . .
DUP. . . , v. . . , v , v
DUP2. . . , v1 , v2. . . , v1 , v2 , v1 , v2
. . . , w. . . , w , w
SWAP. . . , v1 , v2. . . , v2 , v1
DUP_X1. . . , v1 , v2. . . , v2 , v1 , v2
DUP_X2. . . , v1 , v2 , v3. . . , v3 , v1 , v2 , v3
. . . , w , v. . . , v , w , v
DUP2_X1. . . , v1 , v2 , v3. . . , v2 , v3 , v1 , v2 , v3
. . . , v , w. . . , w , v , w
DUP2_X2. . . , v1 , v2 , v3 , v4. . . , v3 , v4 , v1 , v2 , v3 , v4
. . . , w , v1 , v2. . . , v1 , v2 , w , v1 , v2
. . . . , v1 , v2 , w. . . , w , v1 , v2 , w
. . . , w1 , w2. . . , w2 , w1 , w2

常量入栈

指令之前的栈之后的栈
ICONST_n (−1 ≤ n ≤ 5)...... , n
LCONST_n (0 ≤ n ≤ 1)...... , nL
FCONST_n (0 ≤ n ≤ 2)...... , nF
DCONST_n (0 ≤ n ≤ 1)...... , nD
BIPUSH b, −128 ≤ b < 127...... , b
SIPUSH s, −32768 ≤ s < 32767...... , s
LDC cst (int, float, long, double, String or Type)...... , cst
ACONST_NULL...... , null
  • int取值0~5时JVM采用iconst_0、iconst_1、iconst_2、iconst_3、iconst_4、iconst_5指令将常量压入栈中(如果大于5则不用iconst_压栈),
  • 取值-1时采用iconst_m1指令将常量压入栈中。
  • 当int取值**-128 ~ 127** (1字节带符号整数)时,JVM采用bipush指令将常量入栈中。
  • 当int取值**-32768 ~ 32767** (2字节带符号整数)时,JVM采用sipush指令将常量入栈中。
  • 当int取值**-2147483648 ~ 2147483647** (4字节带符号整数)时,JVM采用ldc指令将常量压入栈中。

算术与逻辑

指令之前的栈之后的栈
IADD , LADD , FADD , DADD. . . , a , b. . . , a + b
ISUB , LSUB , FSUB , DSUB. . . , a , b. . . , a - b
IMUL , LMUL , FMUL , DMUL. . . , a , b. . . , a * b
IDIV , LDIV , FDIV , DDIV. . . , a , b. . . , a / b
IREM , LREM , FREM , DREM. . . , a , b. . . , a % b
INEG , LNEG , FNEG , DNEG. . . , a. . . , -a
ISHL , LSHL. . . , a , n. . . , a << n
ISHR , LSHR. . . , a , n. . . , a >> n
IUSHR , LUSHR. . . , a , n. . . , a >>> n
IAND , LAND. . . , a , b. . . , a & b
IOR , LOR. . . , a , b. . . , a 位或 b
IXOR , LXOR. . . , a , b. . . , a ^ b
LCMP. . . , a , b. . . , a == b ? 0 : (a < b ? -1 : 1)
FCMPL , FCMPG. . . , a , b. . . , a == b ? 0 : (a < b ? -1 : 1)
DCMPL , DCMPG. . . , a , b. . . , a == b ? 0 : (a < b ? -1 : 1)

类型转换

指令之前的栈之后的栈
I2B. . . , i. . . , (byte) i
I2C. . . , i. . . , (char) i
I2S. . . , i. . . , (short) i
L2I , F2I , D2I. . . , a. . . , (int) a
I2L , F2L , D2L. . . , a. . . , (long) a
I2F , L2F , D2F. . . , a. . . , (float) a
I2D , L2D , F2D. . . , a. . . , (double) a
CHECKCAST class. . . , o. . . , (class) o

对象、字段和方法

指令之前的栈之后的栈
NEW class. . .. . . , new class
GETFIELD c f t. . . , o. . . , o.f
PUTFIELD c f t. . . , o , v. . .
GETSTATIC c f t. . .. . . , c.f
PUTSTATIC c f t. . . , v. . .
INVOKEVIRTUAL c m t. . , o , v1 , . . , vn. . , o.m (v1, . . vn)
INVOKESPECIAL c m t. . , o , v1 , . . , vn. . , o.m (v1, . . vn)
INVOKESTATIC c m t. . , v1 , . . , vn. . , c .m (v1, . . vn)
INVOKEINTERFACE c m t. . , o , v1 , . . , vn. . , o .m (v1 , . . vn)
INVOKEDYNAMIC m t bsm. . , o , v1 , . . , vn. . , o .m (v1 , . . vn)
INSTANCEOF class. . . , o. . . , o instanceofclass
MONITORENTER. . . , o. . .
MONITOREXIT. . . , o. . .

数组

指令之前的栈之后的栈
NEWARRAY type (任意基元类型). . . , n. . . , new type [n]
ANEWARRAY class. . . , n. . . , new class [n]
MULTIANEWARRAY [...[t n (多维度数组)...,i1 ,...,in...,new t[i1]...[in]
BALOAD , CALOAD , SALOAD. . . , o , i. . . , o [ i ]
IALOAD , LALOAD ,FALOAD , DALOAD. . . , o , i. . . , o [ i ]
AALOAD. . . , o , i. . . , o [ i ]
BASTORE , CASTORE ,SASTORE. . . , o , i , j. . .
IASTORE , LASTORE ,FASTORE , DASTORE. . . , o , i , a. . .
AASTORE. . . , o , i , p. . .
ARRAYLENGTH. . . , o. . . , o .length

跳转

指令之前的栈之后的栈含义
IFEQ, ii == 0 时跳转
IFNE. . . , i. . .i != 0 时跳转
IFLT. . . , i. . .i < 0 时跳转
IFGE. . . , i. . .i >= 0 时跳转
IFGT. . . , i. . .i > 0 时跳转
IFLE. . . , i. . .i <= 0 时跳转
IF_ICMPEQ. . . , i , j. . .i == j 时跳转
IF_ICMPNE, i , ji != j 时跳转
IF_ICMPLT. . . , i , j. . .i < j 时跳转
IF_ICMPGE. . . , i , j. . .i >= j 时跳转
IF_ICMPGT. . . , i , j. . .i > j 时跳转
IF_ICMPLE. . . , i , j. . .i <= j 时跳转
IF_ACMPEQ, o , po == p 时跳转
IF_ACMPNE. . . , o , p. . .o != p 时跳转
IFNULL. . . , o. . .o == null 时跳转
IFNONNULL. . . , o. . .o != null 时跳转
GOTO. . .总是跳转
TABLESWITCH. . . , i. . .总是跳转
LOOKUPSWITCH. . . , i. . .总是跳转

返回

指令之前的栈之后的栈
IRETURN , LRETURN , FRETURN ,DRETURN. . . , a
ARETURN. . . , o
RETURN. . .
ATHROW. . . , o