java虚拟机(七)--常用指令

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ljz2016/article/details/81872452

一、常量入栈指令
分为const,push,ldc。

const系列,常量包含在指令本身里,
push指令主要包括 bipush(8位),sipush(16位)。比如 bipush 50
ldc接收 8位参数(指向常量池中int,float,string的索引),ldc_w接收16位参数。ldw2_w接收的参数指向常量池long,double类型索引。
二、局部变量压栈
xload(i,l,f,d,a),xload_n(i,l,f,d,a,n为0-3),xaload(i,l,f,d,a,b,c,s)

x取值 含义
i int整数
l long整数
f 浮点数
d 双精度浮点数
a 对象索引
b byte
c char
s short

xload_n,表示把第n个局部变量入栈。当局部变量数超过4个时,使用xload。

xaload表示将数组元素入栈,这个指令要求栈顶元素是数组索引,栈顶第二元素是数组引用,在执行完后,会将a[i]入栈。
比如:

public void do(char[] cs,short[] s){
    System.out.println(s[0]);
    System.out.println(cs[0]);
}

部分字节码:

0:getstatic #21
3: aload_2s数组引用入栈
4: iconst_0 把常量0入栈
5: saloads[0] 入栈
6:invokevirtual #43 执行静态方法
9: getstatic #21
12: aload_1cs数组引用入栈
13: iconst_0 把常量0入栈
14: caloadcs[0]入栈

3、出栈并装入局部变量表
出栈装入局部变量表指令,将栈顶元素弹出,然后给局部变量表赋值。
xstore(i,f,l,d,a)
xstore_n(i,f,l,d,a,n为0-3)
xastore(i,f,l,d,a,b,c,s)
和入栈指令意义基本相同,区别是,istore会弹出操作数栈的3个值:值、索引、引用。

public void do(char[] cr,int[] s){
    int a,b,c,x;
    x=99;
    s[0]=77;
}

对应部分字节码:

0: bipush 99
2: istore 6
4: aload_2
5: iconst_0
6: bipush 77
8: iastore
9: return

4、通用型操作
NOP,表示什么都不做。
dup 将栈顶元素复制,并在此压栈
pop把元素从栈顶弹出,并直接废弃。

5、类型转换指令
x2y
x: i,f,l,d;
y:i,f,l,d,c,s,b

在栈上,没有 csb这三种类型,所以x没有它们
6、运算指令
加法:iadd,ladd,fadd,dadd
减法:isub,lsub,fsub,dsub
乘法:imul同上
除法:idiv同上
取余:irem同上
取反:ineg同上
自增:iinc 。
位运算:

  1. 位移:ishl,ishr,iushr,ushl,lshr,lushr
  2. 位或:ior,lor
  3. 位与:iand,land
  4. 位异或:ixor,lxor

7、数组/对象操作指令
创建指令:
指令new创建普通对象,接收一个操作数,指向常,将常量池索引。执行完成后,将对象的引用入栈。

newarray 创建数组,会取出栈顶的数作为数组的大小。
anewarray 创建对象数组,接收参数指向常量池类型
multianewarray创建多维数组,接收2个参数,第一个参数指向常量池类型,第二个参数表示数组维度。

字段访问指令:
getfield,putfield,getstatic,putstatic

8、类型检查指令
两个:checkcast和instanceof。
checkcast用于检查类型强制转换是否可以进行。
instanceof用来判断给定对象是否是一个类的实例,会将判断结果压入操作数栈。
9、数组操作指令
除了xastore,xaload指令,还有获取数组长度的arraylength指令,它弹出栈顶数组引用,将长度入栈。

10、比较控制指令

比较指令:比较栈顶两个元素的大小,并将比较结果入栈。比较指令有:dcmpg,dcmpl,fcmpg,fcmpl,lcmp。
fcmpg遇到NAN,会压入1,fmpl会压入-1。

*条件跳转指令:*ifeq,iflt,ifle, ifne,ifgt,ifge,ifnull,ifnonnull,这些指令都接收两个字节的操作数,用于计算跳转的位置。

比较条件跳转指令:将比较和跳转两个步骤合二为一,指令有if_icmpeq,if_icmpne,if_icmplt,if_icmpgt,if_icmple,if_icmpge,if_acmpeq,ifacmpne

多条件分支跳转:转为switch-case语句设计,主要有tableswitch和lookupswitch。
case的值是连续的,则使用tableswitch,否则使用lookupswitch。

string作为case类型时,比较的是哈希值。

无条件跳转
goto接收2个字节,goto_w接收4个字节。

11、函数调用与返回指令
invokevirtual,invokeinterface,invokespecial,invokestatic,invokedynamic。

指令 作用
invokevitual 虚函数调用,根据对象实际类型派发(函数分发表),支持多态
invokeinterface 接口方法调用,当被调用对象声明为接口时,使用该指令调用接口方法。
invokespecial 调用特殊方法(构造函数,私有方法,父类方法),也就是不会在调用时动态派发的方法
invokestatic 调用类的静态方法
invokedynamic 调用类的动态方法

12、同步控制
monitorenter,monitorexit临界区进入和离开操作,访问当前对象的监视器的计数,如果为0,则可以进入,否则,看持有计数器的线程是否是当前线程,不是的话等待计数器降低到0。每个对象都有对应的监视器。

猜你喜欢

转载自blog.csdn.net/ljz2016/article/details/81872452
今日推荐