一、操作数栈相关指令
1/2_操作数栈
JVM在解释执行的过程中,会为方法分配栈帧,操作数栈是栈帧的重要组成部分。操作数栈用来存放计算的操作数和计算的结果。指令执行前,操作数位于栈顶,指令执行后,结果替换操作数位于栈顶。当方法执行过程中抛出异常时,操作数栈将被清空,并将异常实例压入操作数栈。
2/2_指令举例
- iadd:弹出栈顶的2个int值,相加,和压入栈顶
操作数栈专用指令 - dup:复制栈顶元素
- pop:舍弃栈顶元素
- dup2:复制栈顶的2个单元
- pop2:舍弃栈顶的2个单元
- swap:交换栈顶的2个元素
加载常量指令 - iconst:将-1~5的int值加载至操作数栈
- bipush:将1个字节的int值加载至操作数栈
- sipush:将2个字节的int值加载至操作数栈
- ldc:加载常量池中的常量值
二、局部变量区相关指令
1/2_局部变量区
局部变量区是方法栈帧的重要组成部分之一,用来缓存计算结果。JVM将局部变量区当成一个数组,依次存放 this 指针(仅非静态方法),传入的参数,局部变量。局部变量区中的值,需加载至操作数栈中,方能进行计算,计算完成后,再将结果存储回局部变量数组中,这些加载和存储动作是由相应的指令完成的。
2/2_指令举例
- innc M N:直接作用于局部变量区,M 为非负整数,N 为整数,将局部变量数组的第M个单元中的int值加N
- 加载指令:iload, lload, fload, dload, aload
- 存储指令:istore, lstore, fstore, dstore, astore
三、其他指令
1/4_Java相关指令
具备高层语义的字节码
- new:后跟目标类,生成该类的未初始化对象
- instanceof:后跟目标类,判断栈顶元素是否为目标类/接口的实例,是则压入1,否则压入0
- checkcast:后跟目标类,判断栈顶元素是否为目标类/接口的实例,如果不是则抛出异常
- athrow:将栈顶异常抛出
- monitorenter:为栈顶元素加锁
- monitorexit:为栈顶元素解锁
字段访问指令 - getstatic
- putstatic
- getfield
- putfield
2/4_方法调用指令
- invokestatic:静态方法
- invokespecial
- 私有实例方法
- 构造器
- 使用super关键字调用父类的实例方法
- 使用super关键字调用分类的构造器
- 所实现接口的默认方法
- invokevirtual:非私有实例方法
- invokeinterface:接口方法
- invokedynamic:动态方法
3/4_数组相关指令
- newarray:新建基本类型数组
- anewarray:新建引用类型数组
- multianewarray:生成多维数组
- arraylength:求数组长度
加载指令 - iaload:
存储指令 - iastore
4/4_控制流指令
- goto:无条件跳转
- tableswitch:密集cases
- lookupswitch:稀疏cases
返回指令 - return:返回类型void
- ireturn:返回类型int
- lreturn:返回类型long
- freturn:返回类型float
- dreturn:返回类型double
- areturn:返回类型reference
跳转指令 - iflt 6:当栈顶int值小于0时跳转至偏移量为6的字节码
计算相关(略)