加载和存储指令:
用于将数据在栈帧中的局部变量表和操作数栈之间的来回传输。
将一个局部变量加载到操作栈:
iload、iload_<n>、lload、lload_<n>、fload、fload_<n> 、dload、dload_<n>、aload、aload_<n>
将一个数值从操作数栈保存到局部变量表:
istore、istore_<n>、lstore、lstore_<n>、fstore、fstore_<n>、dstore、dstore_<n>、astore、
astore_<n>
将一个常量加载当操作数栈:
bipush、sipush、ldc、ldc_w、aconst_null、iconst_ml、iconst_<i>、lconst_<l>、
fconst_<f>、dconst_<d>
扩充局部变量表的访问索引的指令:
wide
存储数据的操作数栈和局部变量表主要就是加载和存储指令进行操作。除此之外,还有少量指令,如访问对象的字段或数组元素的指令也会向操作数栈传输数据。
运算指令:
用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶。
加法指令:
iadd、ladd、fadd、dadd
减法指令:
isub、lsub、fsub、dsub
乘法指令:
imul、lmul、fmul、dmul
除法指令:
idiv、ldiv、fdiv、ddiv
求余指令:
irem、lrem、frem、drem
取反指令:
ineg、lneg、fneg、dneg
位移指令:
ishl、ishr、iushr、lshl、lshr、lushr
按位或指令:
ior、lor
按位与指令:
iand、land
按位异或指令:
ixor、lxor
局部变量自增指令:
iinc
比较指令:
dcmpg、dcmpl、fcmpg、fcmpl、lcmp
类型转换指令:
窄化类型转换必须显式使用转换指令来完成:
i2b、 i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f
对象创建指令:
创建类实例的指令:
new
创建数组的指令:
newarray、anewarray、multianewarray
访问类字段和实例字段的指令:
getfield、putfield、getstatic、putstatic
把一个数组元素加载到操作数栈的指令:
baload、caload、saload、iaload、laload、faload、daload、aaload
把一个操作数栈的值存储到数组元素中的指令:
bastore、castore、sastore、iastore、lastore、fastore、dastore、aastore
取数组长度的指令:
arraylength
检查类实例类型的指令:
instanceof、checkcast
操作数栈管理指令:
将操作数栈栈顶的一个元素或者两个元素出栈:
pop、pop2
复制栈顶一个或者两个数值并将复制值或双份的复制值重新压入栈顶:
dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2
将栈最顶端两个值互换:
swap
控制转移指令:
控制指令可以在有条件或者无条件的情况下改变PC寄存器的值。
条件分支:
ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull、if_icmpeq、if_icmpne、
if_icmplt、if_icmpgt、if_icmple、if_icmpge、if_acmpeq、if_acmpne
符合条件分支:
tableswitch、lookupswitch
无条件分支:
goto、goto_w、jsr、jsr_w、ret
方法调用和返回指令:
invokevirtual用于调用对象的实例方法
invokeinterface用于调用接口方法
invokespecial用于调用一些需要特殊处理的实例方法
invokestatic用于调用类方法
invokedynamic用于运行时动态解析出调用点限定符所引用的方法
方法返回指令:
ireturn、lreturn、freturn、dreturn、areturn
异常处理指令:
athrow
idiv
同步指令:
Java虚拟机可以支持方法级和方法内部一段指令序列的同步,这两种同步结构都是通过管程(Monitor)来支持的。
方法级的同步是隐式的,即无需通过字节码指令来控制,它实现在方法调用和返回操作之中。
虚拟机可以从方法常量池的方法表结构中ACC_SYNCHRONIZED访问标志得知一个方法是否声明为同步方法。
当方法被调用时,调用指令会将检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程就要求先成功持有管程,然后才能执行方法,最后当方法完成时(无论是正常完成还是非正常完成)释放管程。在方法执行期间,执行线程持有了管程,其他线程都无法在获取到同一个管程。如果一个同步方法执行期间抛出了异常,并且在方法内部都无法处理此异常,那么这个同步方法所持有的管程将在异常抛出同步方法之外后释放。
monitorenter、monitoerexit