JVM 指令集大全

2,200 阅读4分钟

声明:本文只做字节码介绍,不会谈其底层原理

JVM 指令集中的类型支持

  • opcode: (指令)操作码,首字母 T 代表指定类型 (Type),例如 byte 的 Tipush 是 bipush, "/" 说明暂不支持该类型
opcode byte short int long float double char reference
Tipush bipush sipush / / / / / /
Tconst / / iconst lconst fconst dconst / aconst
Tload / / iload lload fload dload / aload
Tstore / / istore lstore fstore dstore / astore
Tinc / / iinc / / / / /
Taload baload saload iaload laload faload daload caload aaload
Tastore bastore sastore iastore lastore fastore dastore castore aastore
Tadd / / iadd ladd fadd dadd / /
Tsub / / isub lsub fsub dsub / /
Tmul / / imul lmul fmul dmul / /
Tdiv / / idiv ldiv fdiv ddiv / /
Trem / / irem lrem frem drem / /
Tneg / / ineg lneg fneg dneg / /
Tshl / / ishl lshl / / / /
Tshr / / ishr lshr / / / /
Tushr / / iushr lushr / / / /
Tand / / iand land / / / /
Tor / / ior lor / / / /
Txor / / ixor lxor / / / /
i2T i2b i2s / i2l i2f i2d / /
l2T / / l2i l2f l2d / /
f2T / / f2i f2l / f2d / /
d2T / / d2i d2l d2f / / /
Tcmp / / / lcmp / / / /
Tcmpl / / / / fcmpl dcmpl / /
Tcmpg / / / / fcmpg dcmpg / /
if_TcmpOP / / if_icmpOP / / / / if_acmpOP
Treturn / / ireturn lreturn freturn dreturn / areturn

JVM 中的实际类型和计算类型映射关系一览表

  • Actual type: JVM 实际类型
  • Computational type: JVM 计算类型
  • Category: 虚拟机类型
Actual type Computational type Category
boolean int 32-bit
byte int 32-bit
char int 32-bit
short int 32-bit
int int 32-bit
float float 32-bit
reference reference 32-bit
returnAddress returnAddress 32-bit
long long 64-bit
double double 64-bit

Load 和 Store 指令

由于指令较多且大同小异,就不一一翻译了,详情请见参考链接,以下同理

load 和 store 指令用于在 JVM 栈帧的局部变量和操作数栈之间进行值的传递

  • load 一个局部变量到操作数栈顶部:iload, iload_<n>, lload, lload_<n>, fload, fload_<n>, dload, dload_<n>, aload, aload_<n>.
  • load 一个常量到操作数栈顶部:bipush, sipush, ldc, ldc_w, ldc2_w, aconst_null, iconst_m1, iconst_<i>, lconst_<l>, fconst_<f>, dconst_<d>.
  • store 一个操作数栈的值到一个局部变量中:istore, istore_<n>, lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>.

算术指令

算数指令通常用于计算操作数栈顶的两个值,并将计算结果返回到操作数栈。主要有整数类和浮点类计算,像 boolean,byte,short 和 char 也是被当作 int 来进行计算的

  • Add: iadd, ladd, fadd, dadd

  • Subtract: isub, lsub, fsub, dsub

  • Multiply: imul, lmul, fmul, dmul

  • Divide: idiv, ldiv, fdiv, ddiv

  • Remainder: irem, lrem, frem, drem

  • Negate: ineg, lneg, fneg, dneg

  • Shift: ishl, ishr, iushr, lshl, lshr, lushr

    将栈顶第二个数向左/右移栈顶第一个数的低五位值的量。例如 ishl:若栈顶第一个数为 100, 第二个数为 10, 则将 10 左移 100 的低五位值的量 (100 的二进制为 01100100,低五位则为 4,低五位最大值为 32), 将其结果 160 放回栈顶

  • Bitwise OR: ior, lor

  • Bitwise AND: iand, land

  • Bitwise exclusive OR: ixor, lxor

  • Local variable increment: iinc

  • Comparison: dcmpg, dcmpl, fcmpg, fcmpl, lcmp

类型转换指令

JVM 支持以下两类字节转换

  • 小转大
    • float to doubles: f2d
    • long to float, double: l2f, l2d
    • int to long, float, double: i2l, i2f, i2d
  • 大转小
    • long to int: l2i
    • float to int or long: f2i, f2l
    • int to byte, short, or char:i2b,i2s, i2c
    • double to int, long, or float: d2i, d2l,d2f

对象创建和操作

  • 新建实例对象:new
  • 获取数组长度:arraylength
  • 访问类字段,即静态字段:getstatic, putstatic
  • 检查类实例对象和数组:instanceof, checkcast
  • 访问实例字段,即非静态字段:getfield, putfield
  • 新建数组::newarray, anewarray, multianewarray
  • 将数组加载到操作数栈:baload, caload, saload, iaload, laload, faload, daload, aaload
  • 将操作数中的值存储为数组:bastore, castore,sastore, iastore, lastore, fastore, dastore, aastore

操作数栈管理指令

因为操作数栈的结构是栈,所以关于它的操作都离不开出栈入栈,LIFO

pop, pop2, dup, dup2, dup_x1, dup2_x1, dup_x2, dup2_x2, swap

控制转移指令

  • 条件分支(满足一定条件):ifeq, ifne, iflt, ifle, ifgt, ifge, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmplt, if_icmple, if_icmpgt if_icmpge, if_acmpeq, if_acmpne
  • 复合条件分支(满足一定复合条件):tableswitch, lookupswitch
  • 无条件分支(无需满足条件):goto, goto_w, jsr, jsr_w, ret
  • 另外,同算术指令一样,非浮点基础类型使用 int 进行分支判断,且为有符号 int

方法调用和返回指令

  • invokevirtual: 调用实例对象的方法,对对象的类型进行调度,Java 默认的方法调度指令
  • invokeinterface: 调用接口方法,在运行时查找正确的方法进行调用
  • invokespecial: 调用特定的方法,包括实例对象的<init>类的<clinit>和签名多态方法

异常抛出

抛出异常的指令为 athrow ,另外,如果 JVM 检测到异常,也会抛出

同步

针对不同的同步对象,编译后的字节码是不一样的,但是其本质都是一样的,都是依赖 monitor 的状态

对于实例方法和静态方法的同步:ACC_SYNCHRONIZED

对于代码块或实例对象的同步:monitorenter, monitorexit

参考链接