JVM指令

JVM指令 html

JVM指令java

本篇指令碼錶,參考自ASM文檔手冊,若是你對asm感興趣,可到ASM官網下載手冊學習。數組

1、本地變量操做指令(I,L,F,D,A這些前綴表示對int,long,float,double,引用進行操做)學習

本地變量指令集this

指令spa

意義htm

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

超過三的 直接 xLoad n,如ILOAD 4,LLOAD 5blog

將局部變量表中第n個槽的(int|long|float|double)類型變量推送到操做數棧索引

ALOAD_n(0~3)

超過3的 ALOAD 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)

超過3的 ASTORE 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這個值,0是this,壓入操做數棧棧頂

 istore_2//將操做數棧頂的值,這裏就是age,存到局部變量表的第二個槽,也就是a

 iinc 2, 1//將局部變量表中的第二個槽的a加1

 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這些指令

 

2、棧操做指令

                 指令              棧操做前                  棧操做後

POP

...  , v      

...                                                   (v被彈出)

POP2

...  , v1  , v2

...                                            (v1和v2被彈出)

...  , w

...                     (w表示佔用兩個槽的變量,如long,double之類)

DUP

...  , v

...  , v , v            (複製一份)

DUP2

...  , v1  , v2

...  , v1  , v2  , v1 , v2         (複製棧中的兩個值)

...  , w

...  , w, w                             (複製一個long,double型的)

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複製 

 

3、常量操做

 

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_1將1入棧

             //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

  

 

}

 

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)

 

5、轉換

 

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

 

 

6、對象,字段,方法操做

 

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

...

 

7、數組操做

 

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

 

 

8、跳轉語句

 

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

 

9、return

 

 

IRETURN, LRETURN, FRETURN, DRETURN

...  , a

 

ARETURN

...  , o

 

RETURN

...

 

ATHROW

...  , o

 

 

10、泛型

如: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;

 

11、描述符表

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;

12、方法描述符

方法 方法描述符
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;
int[] m(int i, String s) (ILjava/lang/String;)I
Object m(int[] i) ([I)Ljava/lang/Object;
相關文章
相關標籤/搜索