JVM指令

作者: Cajesse佳泽 | 来源:发表于2017-04-05 18:40 被阅读0次

    JVM 指令

    指令由一个字节长度的,代表着某种特定操作含义的数字(操作码)以及跟随其后若干个代表此操作所需参数(操作数)而构成,大多数没有操作数;
    操作码的长度为1个字节. 所以指令集的操作码总数不超过256条
    指令助记符是为了方便阅读指令而语义化的一些符号
    比如00000001的指令的助记符为iload;


    字节码与数据类型

    分类

    加载和存储指令

    指令助记符中 xxx_<n>是操作数为n时的xxx,他们省略掉了显式的操作数,不需要进行去操作数的动作,实际上操作数就隐含在指令中

    • 将一个局部变量加载到操作栈 :
      iload iload_<n>
      fload fload_<n>
      lload lload_<n>
      dload dload_<n>
      aload aload_<n>
    • 将一个数值从操作数栈存储到局部变量表
      istore istore_n
      fstore fstore_n
      lstore lstore_n
      dstore dstore_n
      astore astore_n
    • 将一个常量加载到操作数栈
      bipush sipush
      ldc ldc_w ldc2_w
      aconst_null iconst_ml iconst_<i>
      lconst_<l> fconst_<f> dconst_<d>
    • 扩充局部变量表的访问索引的指令
      wide
    • Demo
    如下的代码
        int a = 1;
        int b = 2;
        int c = 1;
        int d = 5;
        double x = 44.1;
    编译之后的指令为:
        0: iconst_1     // 加载int类型的1
        1: istore_1     // 存储到slot编号为1的局部变量
        2: iconst_2     // 加载int类型的2
        3: istore_2     // 存储到slot编号为2的局部变量
        4: iconst_1    
        5: istore_3
        6: iconst_5     // 加载int类型的5
        7: istore        4    //已经没有省略操作数的istore可用,所以用istore 4
        9: ldc2_w        #9                  // double 44.1d 位于常量池
       12: dstore        5
       14: return
    

    运算指令

    • 加法指令
      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
    • 比较指令
      dcmpg dcmpl fcmpg fcmpl lcmp
    • Demo
    a = a+b; // iadd
    a = a-b; // isub
    a = a*b; // imul
    a = a/b; // idiv
    a = a%b; // irem
    a = a|b; // ior
    a = a&b; // iand
    a = a^b; // ixor
    a = a>>>b; //iushr
    a = a>>b; //ishr
    a = a<<b; //ishl
    a++; //iinc
    

    类型装换指令

    • 宽化类型转换 无须显式指令 但是编译之后也会出现 一个指令 比如 i2f
    • 窄化类型转换 需要显式指令 i2b i2c ....

    对象创建与访问指令

    • 创建类实例 new
    • 创建数组 newarray anewarray multianewarray
    • 访问类字段 getfield putfield getstatic putstatic
    • 访问数组元素 b/c/s/i/l/f/d/a+aload
    • 将一个操作数栈存储到数组元素的指令 b/c/s/i/f/d/a+astore
    • 获取数组长度的指令 arraylength
    • 检查类实例的指令 instanceof checjcast

    操作数栈管理指令

    • 将操作数栈的栈顶一个或两个元素出栈 pop pop2
    • 复制栈顶一个或两个数值并将复制或双份的复制值重新压入栈顶 dup dup2 dup_x1 dup2_x2 dup2_x2
    • 将栈顶最顶端的两个数值互换 swap

    控制转移指令

    • 条件分支 ifeq iflt ifle ...
    • 复合条件分支 tableswitch lookupswitch
    • 无条件分支 goto goto_W

    方法调用和返回指令

    • 调用对象实例方法 invokevirtual
    • 调用接口方法 invokeinterface
    • 调用需要特殊处理的实例方法 invokespecial
    • 调用静态方法 invokestatic
    • 运行时动态解析出调用点限定符所引的方法 invokedynamic

    异常处理指令

    • 显式抛出异常 athrow
    • 运行时异常自动抛出

    同步指令

    • 持有管程 monitorenter
    • 释放管程 monitorexit

    相关文章

      网友评论

        本文标题:JVM指令

        本文链接:https://www.haomeiwen.com/subject/aosxattx.html