zoukankan      html  css  js  c++  java
  • JVM指令

    本篇指令码表,参考自ASM文档手册,如果你对asm感兴趣,可到ASM官网下载手册学习。

    一、本地变量操作指令(I,L,F,D,A这些前缀表示对intlongfloatdouble,引用进行操作)

    本地变量指令集

    指令

    意义

    ILOAD_n(0~3), LLOAD_n(0~3), FLOAD_n(0~3), DLOAD_n(0~3)

    超过三的 直接 xLoad n,ILOAD 4LLOAD 5

    将局部变量表中第n个槽的(int|long|float|double)类型变量推送到操作数栈

    ALOAD_n(0~3)

    超过3ALOAD n,如:ALOAD 5 

    将引用类型的局部变量第n个槽的推送到操作数栈

    ISTORE_n(0~3), LSTORE_n(0~3), FSTORE_n(0~3), DSTORE_n(0~3)

    超过三的xSTORE n

    将操作数栈顶的(int|long|float|double)类型值弹出存到局部变量表的第n个槽中

    ASTORE_n(0~3)

    超过3ASTORE n

    将栈顶引用类型的值存到局部变量表中的第n个槽中

                   IINC var incr                                                            将局部变量表中的第var个变量增加incr,并把新值存到局部变量表

     

    本地变量操作表对应的下标是从0开始的,比如下面一段程序

     

    public void print(int age) {

     

      int a = age;

     

      a++;

     

    }

     

    对应的字节码文件

    stack=1, locals=3, args_size=2//这里的参数为什么是2,因为参数里面有个this,这个this是隐藏的,在JVM中是以参数的形式传递进去的
     iload_1//将局部变量表中的第1个槽,也就是age这个值,0this,压入操作数栈栈顶

     istore_2//将操作数栈顶的值,这里就是age,存到局部变量表的第二个槽,也就是a

     iinc 2, 1//将局部变量表中的第二个槽的a1

     return//方法返回

    注意,如果局部变量中有long或者double类型的值,那么会占用局部变量两个槽,如有局部变量int age,long l, double d, short s, byte b,那么对应的槽应该是1,2,4,6,7

    byte,short,char,int,boolean类型的操作指令统一使用ILOAD或者ISTORE这些指令

     

    二、栈操作指令

                     指令              栈操作前                  栈操作后

    POP

    ...  , v      

    ...                                                   (v被弹出)

    POP2

    ...  , v1  , v2

    ...                                            v1v2被弹出)

    ...  , w

    ...                     (w表示占用两个槽的变量,如longdouble之类)

    DUP

    ...  , v

    ...  , v , v            (复制一份)

    DUP2

    ...  , v1  , v2

    ...  , v1  , v2  , v1 , v2         (复制栈中的两个值)

    ...  , w

    ...  , w, w                             (复制一个longdouble型的)

    SWAP

    ...  , v1  , v2

    ...  , v2  , v1                           交换

    DUP_X1

    ...  , v1  , v2

    ...  , v2 , v1  , v2      复制栈顶值v2,并弹出v1,v2,然后压入v1,v2

    DUP_X2

    ...  , v1  , v2  , v3

    ...  , v3 , v1  , v2  ,  v3   复制v3,并将弹出的3个值入栈

    ...  , w ,  v

    ...  ,  v  , w  , v           复制v,并将复制的两个值入栈(W占两槽)

    DUP2_X1

    ...  , v1  , v2  , v3

    ...  , v2 , v3 , v1  , v2  ,  v3  复制两个值,并将弹出的3个值入栈

    ...  , v ,  w

    ...  , w  , v ,  w   复制2个值,并将弹出的两个值入栈,w占两个槽

    DUP2_X2

    ...  , v1  , v2  , v3  , v4

    ...  , v3 , v4 , v1  , v2  , v3  ,   v4 复制2值,将弹出的4个值入栈

    ...  , w , v1  ,  v2

    ...  , v1  v2  , w , v1  ,  v2   复制2值,将弹出的三个值入栈

    ....  , v1  , v2  ,  w

    ...  , w  , v1  , v2  ,  w    复制1个值,将弹出的3个值入栈

    ...  , w1  , w2

    ...  , w2  , w1  , w2   复制1个值,将弹出的1个值入栈

     举个例子

    public void print(int age, String name) {

      this.age = age;

      this.name = name;

    }

     

    对应的字节码指令

    aload_0   //将this入栈

    dup       //复制一个this

    aload_1  //将age入栈

    putfield #n  //给age复制,这里的n表示一个数字,#n表示索引,对应常量池中的常量 

    aload_2 //将name入栈

    putfield #n //给name复制 

     

    三、常量操作

     

    ICONST_n ( n  5)

    ...

    ...  , n         将整型常量n入栈

    LCONST_n (0  n  1)

    ...

    ...  , nL    将长整型常量n入栈 

    FCONST_n (0  n  2)

    ...

    ...  , nF      float常量入栈

    DCONST_n (0  n  1)

    ...

    ...  , nD     double常量入栈

    BIPUSH b128  b < 127

    ...

    ...  , b        byte常量入栈

    SIPUSH s32768  s < 32767

    ...

    ...  , s        将短整型入栈

    LDC cst  (int, float, long, double, String or Type)

    ...

    ...  , cst     将常量池中值入栈

    ACONST_NULL

    ...

    ... , null    null值入栈

     

    如:public void print(){

      int a1 = 1;              //ICONST_11入栈

                 //ISTORE_1 1存入局部变量表1中,即a1

      int a2 = 10;           //BIPUSH 10

                 //ISTORE 2

      int a3 = 100;       // SIPUSH 100

                //ISTORE 3

      float a4 = 123f;   //LDC #4这个#4是引用了常量池里的值,123

                //FLOAD 4

      

     

    }

     

    四、算术和逻辑操作指令

     

     

    IADD, LADD, FADD, DADD

    ...  , a ,  b

    ...  , a + b               将栈顶的两个值相加,并把结果入栈

    ISUB, LSUB, FSUB, DSUB

    ...  , a ,  b

    ...  , a - b

    IMUL, LMUL, FMUL, DMUL

    ...  , a ,  b

    ...  , a * b

    IDIV, LDIV, FDIV, DDIV

    ...  , a ,  b

    ...  , a / b

    IREM, LREM, FREM, DREM

    ...  , a ,  b

    ...  , a   b

    INEG, LNEG, FNEG, DNEG

    ...  , a

    ...  , -a

    ISHL, LSHL

    ...  , a ,  n

    ...  , a << n

    ISHR, LSHR

    ...  , a ,  n

    ...  , a >> n

    IUSHR, LUSHR

    ...  , a ,  n

    ...  , a >>> n

    IAND, LAND

    ...  , a ,  b

    ...  , a & b

    IOR, LOR

    ...  , a ,  b

    ...  , a | b

    IXOR, LXOR

    ...  , a ,  b

    ...  , a ^ b

    LCMP

    ...  , a ,  b

    ...  , a == b ? 0 : (a < b ? -1 : 1)

    FCMPL, FCMPG

    ...  , a ,  b

    ...  , a == b ? 0 : (a < b ? -1 : 1)

    DCMPL, DCMPG

    ...  , a ,  b

    ...  , a == b ? 0 : (a < b ? -1 : 1)

     

    五、转换

     

    I2B

    ...  , i

    ... , (byte) i

    I2C

    ...  , i

    ... , (char) i

    I2S

    ...  , i

    ... , (short) i

    L2I, F2I, D2I

    ...  , a

    ... , (int) a

    I2L, F2L, D2L

    ...  , a

    ... , (long) a

    I2F, L2F, D2F

    ...  , a

    ... , (float) a

    I2D, L2D, F2D

    ...  , a

    ... , (double) a

    CHECKCAST class

    ...  , o

    ... , (class) o

     

     

    六、对象,字段,方法操作

     

    NEW class

    ...

    ... , new class

    GETFIELD c f t

    ...  , o          

    ...  , o.f

    PUTFIELD c f t                    

    ...  , o ,  v        

    ...

    GETSTATIC c f t

    ...

    ...  , c.f

    PUTSTATIC c f t

    ...  , v

    ...

    INVOKEVIRTUAL c m t

    ...  , o , v1  , ...  , vn

    ... , o.m(v1, ... vn)

    INVOKESPECIAL c m t

    ...  , o , v1  , ...  , vn

    ... , o.m(v1, ... vn)

    INVOKESTATIC c m t

    ...  , v1  , ...  , vn

    ... , c.m(v1, ... vn)

    INVOKEINTERFACE c m t

    ...  , o , v1  , ...  , vn

    ... , o.m(v1, ... vn)

    INVOKEDYNAMIC m t bsm

    ...  , o , v1  , ...  , vn

    ... , o.m(v1, ... vn)

    INSTANCEOF class

    ...  , o

    ... , o instanceof class

    MONITORENTER

    ...  , o

    ...

    MONITOREXIT

    ...  , o

    ...

     

    七、数组操作

     

    NEWARRAY type (for any primitive type)       new基本类型的数组

    ...  , n     数组长度

    ... , new type[n]     new出来的数组引用

    ANEWARRAY class                                        new引用类型的数组

    ...  , n     数组长度

    ... , new class[n]    

    MULTIANEWARRAY [...[t n                            多维数组

    ...  , i1  , ...  , in 各维长度

    ...  ,  new t[i1]...[in]...

    BALOAD, CALOAD, SALOAD                        将指定下标的值入栈

    ...  , o ,  i      i下标,o数组

    ... , o[i]        

    IALOAD, LALOAD, FALOAD, DALOAD

    ...  , o ,  i

    ... , o[i]

    AALOAD

    ...  , o ,  i

    ... , o[i]

    BASTORE, CASTORE, SASTORE

    ...  , o , i ,  j

    ...

    IASTORE, LASTORE, FASTORE, DASTORE

    ...  , o , i ,  a

    ...

    AASTORE

    ...  , o , i ,  p

    ...

    ARRAYLENGTH

    ...  , o

    ... , o.length

     

     

    八、跳转语句

     

    IFEQ

    ...  , i

    ...

    jump if i == 0

    IFNE

    ...  , i

    ...

    jump if i != 0

    IFLT

    ...  , i

    ...

    jump if i < 0

    IFGE

    ...  , i

    ...

    jump if i >= 0

    IFGT

    ...  , i

    ...

    jump if i > 0

    IFLE

    ...  , i

    ...

    jump if i <= 0

    IF_ICMPEQ

    ...  , i ,  j

    ...

    jump if i == j

    IF_ICMPNE

    ...  , i ,  j

    ...

    jump if i != j

    IF_ICMPLT

    ...  , i ,  j

    ...

    jump if i < j

    IF_ICMPGE

    ...  , i ,  j

    ...

    jump if i >= j

    IF_ICMPGT

    ...  , i ,  j

    ...

    jump if i > j

    IF_ICMPLE

    ...  , i ,  j

    ...

    jump if i <= j

    IF_ACMPEQ

    ...  , o ,  p

    ...

    jump if o == p

    IF_ACMPNE

    ...  , o ,  p

    ...

    jump if o != p

    IFNULL

    ...  , o

    ...

    jump if o == null

    IFNONNULL

    ...  , o

    ...

    jump if o != null

    GOTO

    ...

    ...

    jump always

    TABLESWITCH

    ...  , i

    ...

    jump always

    LOOKUPSWITCH

    ...  , i

    ...

    jump always

     

    九、return

     

    IRETURN, LRETURN, FRETURN, DRETURN

    ...  , a

     

    ARETURN

    ...  , o

     

    RETURN

    ...

     

    ATHROW

    ...  , o

    十、泛型

    如:public class Test<T> ==> <T:Ljava/lang/Object;>

    public class Test<T> extends ArrayList<E> ==> <T:Ljava/lang/Object;>Ljava/util/ArrayList<TE;>;

    static <T> Class<? extends T> m (int n) ==> <T:Ljava/lang/Object;>(I)Ljava/lang/Class<+TT;>;

    List<E> ==> Ljava/util/List<TE;>;

    List<?> ==> Ljava/util/List<*>;

    List<? extends Number> ==> Ljava/util/List<+Ljava/lang/Number;>;

    List<? super Integer> ==> Ljava/util/List<-Ljava/lang/Integer;>;

    List<List<String>[]> ==> Ljava/util/List<[Ljava/util/List<Ljava/lang/String;>;>;

    HashMap<K, V>.HashIterator<K> ==> Ljava/util/HashMap<TK;TV;>.HashIterator<TK;>;

    注意:如果是定义定义泛型,比如class Test<T>,方法中的<T>这类T,在写泛型签名的时候应当写成T:Ljava/lang/Object;而不是TT;在其他非定义泛型的位置,写成TT;

    十一、描述符表

    java类型 类型描述符
    boolean Z
    char  C
    byte B
    short S
    int I
    long J
    float F
    double D
    Object Ljava/lang/Object;
    int[] [I
    Object[][] [[Ljava/lang/Object;

    十二、方法描述符

    方法 方法描述符
    void m(int i, float f) (IF)V
    int m(Object o) (Ljava/lang/Object;)I
    int[] m(int i, String s) (ILjava/lang/String;)I
    Object m(int[] i) ([I)Ljava/lang/Object;
  • 相关阅读:
    Appium入坑前必看,附爬虫心得
    app爬虫神器--mitmproxy,mitmdump和appium的安装使用
    小米手机安装charles 证书 无法安装证书,与iphone的unkown,无法联网问题
    mac安装于启动Grafana
    charles单单抓不到google beowser的包
    charles Failed to install helper
    常规反爬复习总结
    FakeUserAgentError('Maximum amount of retries reached') 解决办法
    Java--Set的三个具体实现类
    Java集合--接口
  • 原文地址:https://www.cnblogs.com/honger/p/6815198.html
Copyright © 2011-2022 走看看