您的位置:首页 > 编程语言 > Java开发

JVM指令集

2016-10-01 11:21 148 查看
JVM指令可以分为如下几类:

(1)加载和存储指令   

 加载指令(将局部变量表中数据,或者常量值,及 常量池中数据加载到操作数栈中)         

将一个常量加载到操作数栈:
aconst_null 将null加载到操作数栈
iconst_m1 将-1 加载到操作数栈顶
iconst_0, iconst_1,iconst_2,.........,iconst_5 将int型对应的1-5加载到栈顶
lconst_0,lconst_1 将long型0,1推送到栈顶
fconst_0,fconst_1,fconst_2 将float型0,1,2推送至栈顶
dconst_0,dconst_1 将double型0,1推送至栈顶
bipush 将常量值-128-127整形数据(除去iconst_m加载的几个数据)推送至栈顶
sipush 将一个短整形 -32768-32767(除去bipush,iconst_m加载数据)推送至栈顶
ldc 加载(除去 iconst_m,bipush,sipush)的整形数据推送至栈顶,这个数据是从常量池中拿到的
ldc_w 加载 float 类型数据(除去fconst_m)推送至栈顶
ldc_2w 加载long和double型数据(除去lconst_m和dconst_m)

将局部变量表中的数据加载到操作数栈:
iload_0,iload_1,iload_2,iload_3 将第四个int型局部变量表中的值推送到栈顶
lload_0,...................................lload_3              long
fload_0,,. ................................fload_3             float
dload_0...................................dload_3             double
aload_0....................................aload_3             引用型
注意:int,long,float型数据都只是设置四个,其他的用iload x,指定位置
eg:     iload 6  将局部变量表中第七个int类型的变量值推到栈顶


 存储指令(将操作数栈顶的数据加载到局部变量表中)

istore_0,istore_1..........istore_3 将整形数值存入第i个本地变量
dstore_0..........................dstore_3   double型,还有fstore_0,astore_0...........
若局部变量的个数多于4个时,用istore m 将栈顶的元素送入到局部变量表中第m+1个元素的位置
eg:  astore 7 将操作数栈顶的数据存储到局部变量表中的第8个引用类型的变量中

(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
位移指令:ishl、ishr、iushr、lshl、lshr、lushr
按位或指令:ior、lor
按位与指令:iand、land
按位异或指令:ixor、lxor
局部变量自增指令:iinc

iinc 后面跟两个值,将指定int型变量增加指定的值(如i++,i--.i+=2)
eg:iinc 3,1
表示的为局部变量表中的第四个变量(从0开始)加上1,等价于 a++,a+=1,(a为第四个变量)
注意:a=a+1,a++两者使用的指令的区别


(3)类型转换指令

i2l    将栈顶int型数值强制转换成long型数值并将结果压入栈顶
i2f    将栈顶int型数值强制转换成float型数值并将结果压入栈顶
i2d   将栈顶int型数值强制转换成double型数值并将结果压入栈顶
l2i     将栈顶long型数值强制转换成int型数值并将结果压入栈顶
l2f     将栈顶long型数值强制转换成float型数值并将结果压入栈顶
l2d    将栈顶long型数值强制转换成double型数值并将结果压入栈顶
f2i,f2d,d2i,d2l,d2f,i2b,i2c(int 到char),i2s(int到short)


(4)操作数栈管理指令

pop 将栈顶数值弹出(数值不能使long或double型),1个字节大小
pop2将栈顶的(double或long)弹出,2个字节大小

dup/dup2  复制栈顶1/2个字节的数值,并将复制值压入栈顶
dup_x1:表示复制堆顶偏移1个位置的1个字节的内容,并入到顶栈
eg:操作数栈word1, word2,word1是栈顶,执行后变成word2,word1,word2
dup_x2 表示复制堆顶偏移2个位置的1个字节的内容,并入到顶栈
eg:操作数栈 word1, word2,word3,word1是栈顶,执行后变成word3,word1,word2,word3
dup2_x1 表示复制堆顶偏移1个位置的2 个字节的内容,并入到顶栈
eg:操作数栈 word1, word2,word3,word1是栈顶,执行后变成word2,word3,word1,word2,word
dup2_x2 表示复制堆顶偏移 2个位置的2个字节的内容,并入到顶栈
eg:操作数栈 word1, word2,word3,word4,word1是栈顶,执行后变成word3,word4,word1,word2,word3,word4


(5)控制转移指令

(6)对象创建以及方法、’属性调用指令

创建类实例的指令: new
创建数组的指令:newarray、anewarray
注意: newarray 创建的为基本类型数组(int,char等),anewarray创建的为引用类型的数组(String等)
访问或赋值类字段和实例字段:getstatic,getfield,putstatic,putfield
将一个操作数栈的值存储到数组元素中的指令:bastore,castore,sastore,iastore,fastore,dastore,aastore
eg:
int a[]=new int[5];
a[0]=1;

指令如下:
iconst_5
newarray          int  //创建5个长度的int数组
astore_1           //赋值给 数组a
aload_1
iconst_0
iconst_1
iastore
可以看到 aload_1,iconst_0,iconst_1,iastore 四步是a[0]=1的执行过程,
栈中从下到上依次为 数组a,0,1,iastore指令,可以看出 iastore指令的操作过程,将a[0]=1

取数组的长度: arraylength

方法调用指令和返回指令:
invokevirtual 用于调用对象的实例方法
invokeinterface 用于调用接口方法,他会在运行时搜索一个实现了该接口方法的对象,并调用该方法
invokespecia用于调用 实例初始化方法,私有方法和父类方法
invokestatic 调用类方法
返回指令: ireturn(当返回值是boolean,byte,char,short和int型),lreturn,freturn,dreturn,areturn


扩展操作:

(7)三种循环(while,for,do..while)的调用指令

(8)switch语句,及break,continue的操作指令

  java虚拟机的tablewitch和lookupswitch指令用于支持switch条件,当switch语句中的case分支的条件值比较稀疏时,使用lookupswitch代替tablewitch

(9)异常的操作指令
             athrow 指令
学习指令集能解决常用问题:
 (1) String a="123";           String b="1"+"23";  String c="1"+new String("23");     比较a是否与b,c相同,这是通过javap查看 常量数据的存储,以及 +号运算原理,对字符串的理解
 (2)a=1;        a=a++;         a=a++;   a=a++;   运算完a的值是多少?只能通过javap反编译查看内部运行原理
 (3)java定义枚举类型,javap查看编译器给我们生成的代码
 (4)java实现装箱拆箱的原理
以上种种都需要我们会看JVM指令集,才能去体会java内部运行结构,从本质上去理解代码,有助于我们加深对java的理性认识!

     
                  

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm JVM指令集 javap