1、加载与存储指令
-
xload、xload_<n>(x为i、l、f、d、a,n为索引0、1、2、3):将局部变量加载到操作数栈
-
iload_0:将局部变量0入栈;和 iload 0 一样,但 iload 0占3个字节,iload_0只占1个字节;若n>3,则使用 iload 4
-
iload 4:将局部变量4入栈
-
-
iconst_m1、iconst<i>、lconst<l>、fconst<f>、dconst<d>、aconst_null、bipush、sipush、ldc、ldc_w、ldc2_w:将常量加载到操作数栈
-
iconst_m1:将int型常量-1入栈
-
iconst_<i>(i为数值-1到5):将int型常量-1到5入栈
-
lconst_<l>(l为数值0到1):将long型常量0到1入栈
-
fconst_<f>(f为数值0到2):将float型常量0到2入栈
-
dconst_<d>(d为数值0到1):将double型常量0到1入栈
-
aconst_null:将null入栈
-
bipush <i>:将8位int型常量(-128 - 127)入栈
-
sipush <i>:将16位int型常量(-32768 - 32767)入栈
-
ldc <n>:将8位参数(int、float、String)常量池中的索引位置的数据入栈
-
ldc_w <n>:将16位参数(int、float、String)常量池中的索引位置的数据入栈
-
ldc2_w <n>:将16位参数(long、double)常量池中的索引位置的数据入栈
-
-
xstore、xstore_<n>(x为i、l、f、d、a,n为索引0、1、2、3)、xastore(x为i、l、f、d、a、b、c、s):将数值从操作数栈存储到局部变量表
-
istore_0:将操作数栈顶的int型数据存储到局部变量表中索引为0的位置
-
istore 4:将操作数栈顶的int型数据存储到局部变量表中索引为4的位置
-
-
wide:局部变量表访问索引
2、算数指令
-
加法指令:iadd、ladd、fadd、dadd
-
减法指令:isub、lsub、fsub、dsub
-
乘法指令:imul、lmul、fmul、dmul
-
除法指令:idiv、ldiv、fdiv、ddiv
-
求余指令(余数:remainder):irem、lrem、frem、drem
-
取反指令(取反:negation):ineg、lneg、fneg、dneg
-
自增指令:iinc
-
iinc 1 by 2:将局部变量表中索引为1的int型整数加上2
-
-
位运算指令
-
位移指令:ishl、ishr、iushr、lshl、lshr、lush
-
按位或指令:ior、lor
-
按位与指令:iand、land
-
按位异或指令:ixor、lxor
-
-
比较指令:dcmpg、dcmpl、fcmpg、fcmpl、lcmp
-
比较栈顶两个元素的大小,栈顶下一个元素比栈顶元素比较,大于返回1,相等返回0、小于返回-1
-
dcmpg和dcmpl:针对double类型数据,由于0.0/0.0的结果为NaN,dcmpg会压入1,dcmpl会压入-1
-
fcmpg和fcmpl:针对float类型数据,同上
-
lcmp:由于long型没有NaN值,不需要区分
-
3、类型转换指令
-
宽化类型转换
-
i2l、i2f、i2d:将int型(byte、short、char都看作int)转为long、float、double
-
l2f、l2d:将long型转为float、double
-
f2d:将float型转为double
-
-
窄化类型转换
-
i2b、i2s、i2c:将int型转为byte、short、char
-
l2i:将long型转为int
-
f2i、f2l:将float型转为int、long
-
d2i、d2l、d2f:将double型转为int、long、float
-
将long型转为byte:l2i,i2b
-
4、对象创建与访问指令
-
创建指令
-
new:创建类实例,并将堆中的引用入栈
-
newarray:创建基本类型数组,并将堆中的引用入栈
-
anewarray:创建引用类型数组,并将堆中的引用入栈
-
multianewarray:创建多维数组,并将堆中的引用入栈
-
-
字段访问指令
-
getstatic:将类变量入栈
-
putstatic:将类变量出栈
-
getfield:将实例变量入栈
-
putfield:将实例变量出栈
-
-
数组操作指令
-
baload(byte和boolean)、caload、saload、iaload、laload、faload、daload、aaload:将数组元素入栈
-
xaload执行时,要求操作数栈顶元素为数组索引i,栈顶顺位第2个元素为数组引用a,该指令弹出栈顶两个元素,并将a[i]重新入栈
-
-
bastore(byte和boolean)、castore、sastore、iastore、lastore、fastore、dastore、aastore:将栈的值存储到数组中
-
xastore执行前,操作数栈顶需要三个元素:值、索引、数组引用,xastore会弹出这3个值,并将值赋给数组中指定索引的位置
-
-
arraylength:弹出栈顶数组元素,获取数组长度,将长度入栈
-
-
类型检查指令
-
instanceof:判断对象是否为一个类的实例,将结果入栈
-
checkcast:检查类型强制转换是否可以进行;若可以,不会改变栈,否则抛出ClassCastException
-
5、方法调用与返回指令
-
方法调用指令(调用完会将栈顶两个元素出栈)
-
invokevirtual:调用虚方法,编译期间不能确定的方法;除去final修饰的方法(final修饰的方法是非虚方法),调用的都是虚方法
-
invokeinterface:调用接口方法,编译期间不能确定的方法;调用的都是虚方法
-
invokespecial:调用构造器<init>、私有、父类方法,编译期间可以确定的方法;调用的都是非虚方法
-
invokestatic:调用静态方法,编译期间可以确定的方法;调用的都是非虚方法
-
invokedynamic:动态解析需要调用的方法,再执行,编译期间不能确定的方法;主要体现在lambda表达式
-
-
方法返回指令
-
ireturn(方法返回值为boolean、byte、char、short、int)、lreturn、freturn、dreturn、areturn:将当前操作数栈顶元素弹出,将此元素压入调用者函数的操作数栈中
-
return:方法返回值为void、实例初始化方法、类和接口初始化方法
-
6、操作数栈管理指令
-
pop、pop2:出栈
-
pop:弹出栈顶一个槽位大小(4个字节)的数据,例如一个int型数据、一个float型数据
-
pop2:弹出栈顶两个槽位大小(8个字节)的数据,例如两个int型数据、一个long型数据
-
-
dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2:复制栈顶一个或两个数并将复制值或双份复制值重新入栈
-
dup:复制一个字节大小的数据
-
dup2:复制两个字节大小的数据
-
dup_x1:复制一个字节大小的数据,并将复制的数据插入到栈顶2个(1+1,dup和x后的系数相加)槽位下
-
dup2_x1:复制两个字节大小的数据,并将复制的数据插入到栈顶3个(2+1,dup和x后的系数相加)槽位下
-
-
slot:将栈顶两个槽位的数值交换
-
nop:什么都不做,通常用于调试和占位
7、控制转移指令
-
条件跳转指令
-
ifeq、ifne、iflt、ifle、ifgt、ifge、ifnull、ifnonnull:弹出栈顶元素,满足某一条件时,跳转到给定位置(boolean、byte、char、short都按照int型处理)
-
ifeq:栈顶int型数值等于0时跳转
-
ifne:栈顶int型数值不等于0时跳转
-
iflt:栈顶int型数值小于0时跳转
-
ifle:栈顶int型数值小于等于0时跳转
-
ifgt:栈顶int型数值大于0时跳转
-
ifge:栈顶int型数值大于等于0时跳转
-
ifnull:为null时跳转
-
ifnonnull:不为null时跳转
-
-
-
比较条件跳转指令
-
if_icmpeq、if_icmpne、if_icmplt、if_icmple、if_icmpgt、if_icmpge、if_acmpeq、if_acmpne:比较并跳转
-
if_icmpeq:比较栈顶两个int型数值大小,栈顶下一个元素等于栈顶元素时跳转
-
if_icmpne:比较栈顶两个int型数值大小,栈顶下一个元素不等于栈顶元素时跳转
-
if_icmplt:比较栈顶两个int型数值大小,栈顶下一个元素小于栈顶元素时跳转
-
if_icmple:比较栈顶两个int型数值大小,栈顶下一个元素小于等于栈顶元素时跳转
-
if_icmpgt:比较栈顶两个int型数值大小,栈顶下一个元素大于栈顶元素时跳转
-
if_icmpge:比较栈顶两个int型数值大小,栈顶下一个元素大于等于栈顶元素时跳转
-
if_acmpeq:比较栈顶两个引用类型数值,相等时跳转
-
if_acmpne:比较栈顶两个引用类型数值,不相等时跳转
-
-
-
多条件分支跳转
-
tableswitch:用于switch条件中case值连续时跳转
-
lookupswitch:用于switch条件中case值不连续时跳转,出于效率考虑,会将case值进行大小排序
-
若switch后的值为String(JDK7新特性),会计算每个case对应的String的哈希值进行大小排序;哈希值相等了在进行equals()比较
-
-
-
无条件跳转
-
goto:接收两个字节的操作数(偏移量),直接跳转
-
goto_w:接收四个字节的操作数(偏移量),直接跳转
-
8、异常处理指令
-
athrow:显示抛出异常(throw语句)
-
编译时异常和手动thow的异常都会用athrow声明,运行时异常不会用athrow声明
-
-
异常表:使用try-catch、try-catch、try-catch-finally时会生成异常表
9、同步控制指令
-
方法级同步:方法声明为synchronized时,没有在字节码指令中体现,而是在方法表结构中标注为synchronized
-
代码块同步:同步的代码在monitorenter和monitorexit之间
-
monitorenter:将对象监视器的计数器改为1(加锁)
-
monitorexit:将对象监视器的计数器改为0(解锁)
-