JAVA操作码相关指令介绍(2)

本文深入解析JAVA字节码命令,涵盖数值运算、类相关操作、数组操作及方法调用返回指令,助你理解JAVA底层执行逻辑。

上一章介绍了JAVA一些基础类型转化以及局部变量的入栈等操作JAVA操作码相关指令介绍(1)。这章继续给大家介绍下字节码命令。

JAVA数值运算

JAVA里面提供的整数运算都基于intlong类型的运算。当小于int类型的类型参与计算的时候,会将他们转化为int类型。

1.数值之间相加

操作码操作数备注
iadd从栈中弹出两个int类型数,相加之后将所得int类型结果压回栈
ladd从栈中弹出两个long类型数,相加之后将所得long类型结果压回栈
fadd从栈中弹出两个float类型数,相加之后将所得float类型结果压回栈
dadd从栈中弹出两个double类型数,相加之后将所得double类型结果压回栈
iincvindex,const把常量与一个位于vindex位置的int类型局部变量相加
wideiinc,indexconst把常量与一个位于vindex位置的int类型局部变量相加

2.数值之间相减

栈顶端的充当减数,次顶端的充当被减数

操作码操作数备注
isub从栈中弹出两个int类型数,相减所得int类型结果压回栈
lsub从栈中弹出两个long类型数,相减所得long类型结果压回栈
fsub从栈中弹出两个float类型数,相减所得float类型结果压回栈
dsub从栈中弹出两个double类型数,相减所得double类型结果压回栈

3.数值之间乘法

操作码操作数备注
imul从栈中弹出两个int类型数,相乘所得int类型结果压回栈
lmul从栈中弹出两个long类型数,相乘所得long类型结果压回栈
fmul从栈中弹出两个float类型数,相乘所得float类型结果压回栈
dmul从栈中弹出两个double类型数,相乘所得double类型结果压回栈

4.数值之间除法

次顶端的数除以顶端的数。如果整数被0除,会抛出相关异常。

操作码操作数备注
idiv从栈中弹出两个int类型数,相除所得int类型结果压回栈
ldiv从栈中弹出两个long类型数,相除所得long类型结果压回栈
fdiv从栈中弹出两个float类型数,相除所得float类型结果压回栈
ddiv从栈中弹出两个double类型数,相除所得double类型结果压回栈

5.数值之间取余

操作码操作数备注
irem从栈中弹出两个int类型数,取余所得int类型结果压回栈
lrem从栈中弹出两个long类型数,取余所得long类型结果压回栈
frem从栈中弹出两个float类型数,取余所得float类型结果压回栈
drem从栈中弹出两个double类型数,取余所得double类型结果压回栈

6.数值之间取反

操作码操作数备注
ineg从栈中弹出两个int类型数,取反将所得int类型结果压回栈
lneg从栈中弹出两个long类型数,取反将所得long类型结果压回栈
fneg从栈中弹出两个float类型数,取反将所得float类型结果压回栈
dneg从栈中弹出两个double类型数,取反将所得double类型结果压回栈

7.数值之间位移

操作码操作数备注
ishl将int型数值左移位指定位数并将结果压入栈顶
ishr将int型数值右(符号)移位指定位数并将结果压入栈顶
iushr将int型数值右(无符号)移位指定位数并将结果压入栈顶
lshl将long型数值左移位指定位数并将结果压入栈顶
lshr将long型数值右(符号)移位指定位数并将结果压入栈顶
lshr将long型数值右(无符号)移位指定位数并将结果压入栈顶

7.数值之间或

操作码操作数备注
ior将栈顶两int型数值作“按位或”并将结果压入栈顶
lor将栈顶两long型数值作“按位或”并将结果压入栈顶

8.数值之间与

操作码操作数备注
iand将栈顶两int型数值作“按位与”并将结果压入栈顶
land将栈顶两long型数值作“按位与”并将结果压入栈顶

9.数值之间异或

操作码操作数备注
ixor将栈顶两int型数值作“按位异或”并将结果压入栈顶
lxor将栈顶两long型数值作“按位异或”并将结果压入栈顶

10.数值之间比较

操作码操作数备注
dcmpg比较栈顶两double型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将1压入栈顶
dcmpl比较栈顶两double型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将-1压入栈顶
fcmpg比较栈顶两float型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将1压入栈顶
fcmpl比较栈顶两float型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将-1压入栈顶
lcmp比较栈顶两long型数值大小,并将结果(1,0,-1)压入栈顶
ifeq当栈顶int型数值等于0时跳转
ifne当栈顶int型数值不等于0时跳转
iflt当栈顶int型数值小于0时跳转
ifge当栈顶int型数值大于等于0时跳转
ifgt当栈顶int型数值大于0时跳转
ifle当栈顶int型数值小于等于0时跳转

JAVA类相关操作

1.类属性字段操作

操作码操作数备注
new创建类实例
newarray创建一个指定原始类型(如int,float,char…)的数组,并将其引用值压入栈顶
anewarray创建一个引用型(如类,接口,数组)的数组,并将其引用值压入栈顶
multianewarray创建指定类型和指定维度的多维数组(执行该指令时,操作栈中必须包含各维度的长度值),并将其引用值压入栈顶
getfield获取指定类的实例域,并将其值压入栈顶
putfield为指定的类的实例域赋值
getstatic获取指定类的静态域,并将其值压入栈顶
putstatic为指定的类的静态域赋值

2.数组操作

操作码操作数备注
baload将boolean或byte型数组指定索引的值推送至栈顶
caload将char型数组指定索引的值推送至栈顶
saload将short型数组指定索引的值推送至栈顶
iaload将int型数组指定索引的值推送至栈顶
laload将long型数组指定索引的值推送至栈顶
faload将float型数组指定索引的值推送至栈顶
daload将double型数组指定索引的值推送至栈顶
aaload将引用型数组指定索引的值推送至栈顶
bastore将栈顶boolean或byte型数值存入指定数组的指定索引位置
castore将栈顶char型数值存入指定数组的指定索引位置
sastore将栈顶short型数值存入指定数组的指定索引位置
iastore将栈顶int型数值存入指定数组的指定索引位置
fastore将栈顶float型数值存入指定数组的指定索引位置
dastore将栈顶double型数值存入指定数组的指定索引位置
aastore将栈顶引用型数值存入指定数组的指定索引位置

3.方法调用和返回指令

调用之后的结果依旧是在操作栈的

操作码操作数备注
invokevirtual用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),这也是Java语言中最常见的方法分派方式。
invokeinterface用于调用接口方法,它会在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。
invokespecial用于调用一些需要特殊处理的实例方法,包括实例初始化方法(§2.9)、私有方法和父类方法。
invokestatic调用类方法(static方法)。
ireturn从当前方法返回int
lreturn从当前方法返回long
areturn从当前方法返回对象引用
return从当前方法返回void

4.其他操作

操作码操作数备注
monitorenter获得对象的锁,用于同步方法或同步块
monitorexit释放对象的锁,用于同步方法或同步块
athrow抛出异常信息
jsr跳转至指定16位offset位置,并将jsr下一条指令地址压入栈顶
jsr_w跳转至指定32位offset位置,并将jsr_w下一条指令地址压入栈顶
goto_w无条件跳转(宽索引)

大多数的操作码已经在这两章中介绍了,小伙伴们可以简单的对自己的程序进行编译查看下操作码(javap -help)。对于一些简单的程序就可以自己去查看。

转载于:https://juejin.im/post/5d046ff5f265da1ba9157b45

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值