Java字节码

在 Java 虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息。

1.将常量压入操作数栈中的指令

(1)iconst_n、 lconst_n、fconst_n、dconst_n

  • aconst_null ——将null对象引用压入栈
  • iconst_m1 ——将int类型常量-1压入栈
  • iconst_n —— 将int类型常量n压入栈 (n为任意整数)
  • lconst_n——将long类型常量n压入栈
  • fconst_n——将float类型常量n压入栈
  • dconst_n——将double类型常量n压入栈

(2)bipush、sipush

  • bipush——将一个8位带符号整数压入栈
  • sipush——将16位带符号整数压入栈

(3)idc

  • ldc ——把常量池中的项压入栈
  • ldc_w ——把常量池中的项压入栈(使用宽索引)
  • ldc2_w——把常量池中long类型或者double类型的项压入栈(使用宽索引)

2.将操作数栈中的值存入局部变量表中的指令

(1)istore_n、lstore_n、fstore_n、dstore_n、astore_n

  • istore_n——将int类型值存入局部变量n (n为任意整数)
  • lstore_n—— 将long类型值存入局部变量n
  • fstore_n——将float类型值存入局部变量n
  • dstore_n——将double类型值存入局部变量n

(2)astore_n、iastore、lastore、fastore 、dastore 、aastore 、bastore、castore、sastore

  • astore_n——将引用类型或returnAddress类型值存入局部变量n
  • iastore——将int类型值存入数组中
  • lastore——将long类型值存入数组中
  • fastore ——将float类型值存入数组中
  • dastore——将double类型值存入数组中
  • aastore——将引用类型值存入数组中
  • bastore——将byte类型或者boolean类型值存入数组中
  • castore ——将char类型值存入数组中
  • sastore——将short类型值存入数组中

(3)wide

  • wide——使用附加字节扩展局部变量索引

3.从栈中给局部变量中装载值的指令

(1)iload_n、lload_n 、fload_n、dload_n

  • iload_n——从局部变量n中装载int类型值
  • lload_n——从局部变量n中装载long类型值
  • fload_n——从局部变量n中装载float类型值
  • dload_n——从局部变量n中装载double类型值

(2)aload_n、iaload、laload、faload 、daload、aaload、baload、caload、saload

  • aload_n——从局部变量n中装载引用类型值
  • iaload——从数组中装载int类型值
  • laload——从数组中装载long类型值
  • faload——从数组中装载float类型值
  • daload——从数组中装载double类型值
  • aaload ——从数组中装载引用类型值
  • baload——从数组中装载byte类型或boolean类型值
  • caload——从数组中装载char类型值
  • saload ——从数组中装载short类型值

4.类型转化的指令(i2l、i2d、l2f、f2d、i2b、i2c、i2s…)

  • i2l——把int类型的数据转化为long类型
  • i2f——把int类型的数据转化为float类型
  • i2d——把int类型的数据转化为double类型
  • l2i——把long类型的数据转化为int类型
  • l2f——把long类型的数据转化为float类型
  • l2d——把long类型的数据转化为double类型
  • f2i——把float类型的数据转化为int类型
  • f2l ——把float类型的数据转化为long类型
  • f2d——把float类型的数据转化为double类型
  • d2i ——把double类型的数据转化为int类型
  • d2l ——把double类型的数据转化为long类型
  • d2f——把double类型的数据转化为float类型
  • i2b——把int类型的数据转化为byte类型
  • i2c—— 把int类型的数据转化为char类型
  • i2s —— 把int类型的数据转化为short类型

5.整数运算(iadd、ladd 、isub、imul 、idiv、irem 、ineg 、iinc …)

  • iadd——执行int类型的加法
  • ladd—— 执行long类型的加法
  • isub——执行int类型的减法 lsub——执行long类型的减法
  • imul——执行int类型的乘法
  • lmul——执行long类型的乘法
  • idiv——执行int类型的除法
  • ldiv——执行long类型的除法
  • irem——计算int类型除法的余数
  • lrem——计算long类型除法的余数
  • ineg——对一个int类型值进行取反操作
  • lneg——对一个long类型值进行取反操作
  • iinc (如1 by 1) ——把一个常量值加到一个int类型的局部变量上

6.逻辑运算

(1)移位操作 (ishl、lshl、ishr、lshr、iushr、lushr)

  • ishl——执行int类型的向左移位操作
  • lshl——执行long类型的向左移位操作
  • ishr—— 执行int类型的向右移位操作
  • lshr——执行long类型的向右移位操作
  • iushr——执行int类型的向右逻辑移位操作
  • lushr——执行long类型的向右逻辑移位操作

(2)按位布尔运算 (iand、land、ior 、lor、ixor、lxor)

  • iand——对int类型值进行“逻辑与”操作
  • land——对long类型值进行“逻辑与”操作
  • ior——对int类型值进行“逻辑或”操作
  • lor——对long类型值进行“逻辑或”操作
  • ixor——对int类型值进行“逻辑异或”操作
  • lxor——对long类型值进行“逻辑异或”操作

(3)浮点运算

  • fadd——执行float类型的加法
  • dadd——执行double类型的加法
  • fsub——执行float类型的减法
  • dsub——执行double类型的减法
  • fmul——执行float类型的乘法
  • dmul——执行double类型的乘法
  • fdiv——执行float类型的除法
  • ddiv——执行double类型的除法
  • frem——计算float类型除法的余数
  • drem—— 计算double类型除法的余数
  • fneg——将一个float类型的数值取反
  • dneg——将一个double类型的数值取反

7.对象和数组指令

(1)对象操作指令 (getstatic、putstatic…)

  • new——创建一个新对象
  • checkcast——确定对象为所给定的类型
  • getfield——从对象中获取字段
  • putfield——设置对象中字段的值
  • getstatic——从类中获取静态字段
  • putstatic——设置类中静态字段的值
  • instanceof——判断对象是否为给定的类型

(2)数组操作指令 (newarray、arraylength…)

  • newarray——分配数据成员类型为基本上数据类型的新数组
  • anewarray——分配数据成员类型为引用类型的新数组
  • arraylength——获取数组长度
  • multianewarray——分配新的多维数组

7.控制流相关指令

(1)条件分支指令 (ifeq、iflt 、ifge 、ifle、if_icmpcq、if_icmplt、if_icmple、if_icmpne、ifnull、if_acmpeq 、if_acmpnc、… )

  • ifeq——如果等于0,则跳转
  • ifne—— 如果不等于0,则跳转
  • iflt—— 如果小于0,则跳转
  • ifge——如果大于等于0,则跳转
  • ifgt——如果大于0,则跳转
  • ifle——如果小于等于0,则跳转
  • if_icmpcq—— 如果两个int值相等,则跳转
  • if_icmpne——如果两个int类型值不相等,则跳转
  • if_icmplt——如果一个int类型值小于另外一个int类型值,则跳转
  • if_icmpge——如果一个int类型值大于或者等于另外一个int类型值,则跳转
  • if_icmpgt——如果一个int类型值大于另外一个int类型值,则跳转
  • if_icmple——如果一个int类型值小于或者等于另外一个int类型值,则跳转
  • ifnull——如果等于null,则跳转
  • ifnonnull——如果不等于null,则跳转
  • if_acmpeq—— 如果两个对象引用相等,则跳转
  • if_acmpnc——如果两个对象引用不相等,则跳转

(2)比较指令 (lcmp、fcmpl 、fcmpg 、dcmpl、dcmpg )

  • lcmp——比较long类型值
  • fcmpl——比较float类型值(当遇到NaN时,返回-1)
  • fcmpg—— 比较float类型值(当遇到NaN时,返回1)
  • dcmpl——比较double类型值(当遇到NaN时,返回-1)
  • dcmpg—— 比较double类型值(当遇到NaN时,返回1)

// NaN 是计算机科学中数值数据类型的一类值,表示未定义或不可表示的值。

(3)无条件转移指令 (goto、tableswitch、lookupswitch)

  • goto——无条件跳转
  • goto_w——无条件跳转(宽索引)

// 表跳转指令

  • tableswitch——通过索引访问跳转表,并跳转
  • lookupswitch——通过键值匹配访问跳转表,并执行跳转操作

(4)异常 (athrow)

  • athrow——抛出异常或错误

(5)finally子句 (jsr、jsr_w、rct)

  • jsr—— 跳转到子例程
  • jsr_w——跳转到子例程(宽索引)
  • rct—— 从子例程返回

(6)方法调用与返回

<1>方法调用指令(invokcvirtual、invokespecial、invokestatic、invokcinterface)

  • invokcvirtual——运行时按照对象的类来调用实例方法
  • invokespecial——根据编译时类型来调用实例方法
  • invokestatic——调用类(静态)方法
  • invokcinterface——调用接口方法

<2>方法返回指令 (ireturn 、lreturn、freturn、dreturn、areturn、return)

  • ireturn——从方法中返回int类型的数据
  • lreturn——从方法中返回long类型的数据
  • freturn——从方法中返回float类型的数据
  • dreturn—— 从方法中返回double类型的数据
  • areturn——从方法中返回引用类型的数据
  • return—— 从方法中返回,返回值为void

(8)线程同步 (montiorenter、monitorexit)

  • montiorenter——进入并获取对象监视器
  • monitorexit—— 释放并退出对象监视器