jvm字节码指令

73 篇文章 0 订阅

 aload: 就是从局部变量表中,把对象类型加载到操作数栈中;

iload: 就是从局部变量表中,把int类型加载到操作数栈中;

fload: 就是从局部变量表中,把float类型加载到操作数栈中;

dload: 就是从局部变量表中,把double类型加载到操作数栈中;

lload: 就是从局部变量表中,把long类型加载到操作数栈中;

sload: 就是从局部变量表中,把short类型加载到操作数栈中;

cload: 就是从局部变量表中,把char类型加载到操作数栈中;

bload: 就是从局部变量表中,把byte类型加载到操作数栈中;

包含load,push,ldc,const的指令,都是把数据从局部变量表中,加载到操作数栈中;
包含store指令的,都是把数据,从操作数栈中,存储到,局部变量表中;

算数指令就是把操作数栈的数据,取出2个然后进行计算,得出结果放入操作数栈;

加法指令:iadd,ladd,fadd,dadd;
减法指令: isub,lsub,fsub,dsub;
乘法指令: imul,lmul,fmul,dmul;
除法指令: idiv,ldiv,fdiv,ddiv;
求余指令:irem,lrem,frem,drem;
取反指令: ineg,lneg,fneg,dneg;
自增指令: iinc;
比较指令: dcmpg,dcmpl,fcmpg,fcmpl,lcmp;
位移指令: ishl,ishr,iushr,lshl,lshr,lushr;
按位或指令: ior,lor;
按位与指令: iand,land;
按位异或指令: ixor,lxor;

宽化类型转换,就是从小范围类型向大范围类型的安全转换;

从int类型转换到long: i2l;
从int类型转换到float: i2f;
从int类型转换到double类型:i2d;

从long类型转换到float: l2f;
从long类型转换到double: l2d;

从float类型转换到double: f2d;

窄化类型转换
从int类型到byte,short,char类型对应的指令有:i2b,i2s,i2c;
从long类型到int类型,对应的指令:l2i;
从float类型到int或者long类型,对应的指令: f2i,f2l;
从double类型到int,long,float类型,对应的指令: d2i,d2l,d2f;

创建数组的指令

newarray: 创建基本类型数组
anewarray: 创建引用类型数组
multianewarray: 创建多维数组

new:创建类实例的指令

字段访问指令

访问类字段(static字段,或者称为类变量)的指令:getstatic,putstatic;
访问类实例字段(非static字段,或者称为实例变量)的指令:getfield,putfield;
get压入操作数栈操作,put从操作数栈移除操作
 

数组操作指令

把一个数组元素加载到操作数栈的指令(弹出操作数栈2个值 ,找到堆空间那个数组的值,然后放入操作数栈):baload,caload,saload,iaload,laload,faload,daload,aaload;


把一个操作数栈的值存储到数组元素中的指令(弹出操作数栈中3个数据 值 索引 数组引用, 然后去找堆空间那个数组, 修改他的值):bastore,castore,sastore,iastore,lastore,fastore,dastore,aastore;


弹出栈顶的数组元素,获取数组的长度,将长度压入栈的指令:arraylength;

类型检查指令

checkcast:用于检查类型强制转换是否可以进行,如果可以进行,那么checkcast指令不会改变操作数栈,否则它会抛出ClassCastException异常;


instanceof:用来判断给定对象是否是某一个类的实例,他会将判断结果压入操作数栈;

方法调用指令

invokevirtual:用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),支持多态,这也是java语言中最常见的方法分派方式;

invokeinterface:用于调用接口方法,他会在运行时搜索由特定对象所实现的这个接口方法,并找出适合的方法进行调用;

invokespecial:用于调用一些需要特殊处理的实例方法,包括实例初始化方法(构造器),私有方法和父类方法,这些方法都是静态类型绑定的,不会在调用时进行动态派发;

invokestatic:用于调用命名类中的类方法(static方法),这是静态绑定的;

invokedynamic:调用动态绑定的方法,这个是jdk1.7后新加入的指令,用于运行时动态解析出调用点限定符所引用的方法,并执行该方法,前面4条调用指令的分派逻辑都固话在java虚拟机内部,而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的;

方法返回指令
return: void类型;
ireturn: int类型;
lreturn: long类型;
freturn: float类型;
dreturn: double类型;
areturn: 引用类型;

操作数栈管理指令

pop: 将栈顶的1个Slot数值出栈,例如一个short类型数值;
pop2:将栈顶的2个Slot数值出栈,例如1个double类型数值,或者2个int类型数值;

swap:将栈顶2个Slot数值位置交换;

nop:表示什么都不做,用于调试,占位;

不带x的指令是复制栈顶数据,并压入栈顶;
dup:用于复制1个Slot的数据,例如1个int或者1个引用类型数据;
dup2:用于复制2个Slot的数据,例如1个long,或者2个int,或者1个int+1个float类型数据;

带_x的指令是复制栈顶数据,并插入栈顶以下的某个位置;
dup_x1插入位置:1+1=2,即栈顶2个Slot下面;
dup_x2插入位置:1+2=3,即栈顶3个Slot下面;

dup2_x1插入位置:2+1=3,即栈顶3个Slot下面;
dup2_x2插入位置:2+2=4,即栈顶4个Slot下面;


 

条件跳转指令

ifeq:当栈顶int类型数值等于0时跳转;
fine:当栈顶int类型数组不等于0时跳转;
iflt:当栈顶int类型数值小于0时跳转;
ifle:当栈顶int类型数值小于等于0时跳转;
ifgt:当栈顶int类型数值大于0时跳转;
ifge:当栈顶int类型数值大于等于0时跳转;
ifnull:为null时跳转;
ifnonnull:不为null时跳转;


比较条件跳转指令
if_icmpeq:比较栈顶2个int类型数值大小,当前者等于后者时跳转;
if_icmpne:比较栈顶2个int类型数值大小,当前者不等于后者时跳转;
if_icmplt:比较栈顶2个int类型数值大小,当前者小于后者时跳转;
if_icmple:比较栈顶2个int类型数值大小,当前者小于等于后者时跳转;
if_icmpgt:比较栈顶2个int类型数值大小,当前者等大于后者时跳转;
if_icmpge:比较栈顶2个int类型数值大小,当前者等大于等于后者时跳转;

if_acmpeq:比较栈顶2个引用类型数值,当结果相等时跳转;
if_acmpne:比较栈顶2个引用类型数值,当结果不相等时跳转;

多条件分支跳转指令
tableswitch: 用于switch条件跳转,case值连续;
lookupswitch: 用于switch条件跳转,case值不连续;

无条件跳转指令
goto: 无条件跳转;
goto_w: 无条件跳转(宽索引);
jsr: 跳转至16位offset位置,并将jsr下一条指令地址压入栈顶;
jsr_w: 跳转至指定32位offer位置,并将jsr_w下一条指令地址压入栈顶;
ret: 返回至由指定的局部变量所给出的指令位置(一般与jsr,jsr_w联合使用);

方法内指定指令序列的同步

monitorenter:如果当前对象的监视器计数器为0,则他会被准许进入,若为1,则判断持有当前监视器的线程释放为自己,如果是,则进入,否则等待,直到对象的监视器计数器为0,才会被允许进入同步块;


monitorexit: 线程退出同步块时使用

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值