本篇指令碼表,參考自ASM文檔手冊,如果你對asm感興趣,可到ASM官網下載手冊學習。
一、本地變量操作指令(I,L,F,D,A這些前綴表示對int,long,float,double,引用進行操作)
|   本地變量指令集  |  
          |
|   指令  |  
             意義  |  
          
|   ILOAD_n(0~3), LLOAD_n(0~3), FLOAD_n(0~3), DLOAD_n(0~3) 超過三的 直接 xLoad n,如ILOAD 4,LLOAD 5  |  
             將局部變量表中第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這些指令
二、棧操作指令
指令 棧操作前 棧操作后
|   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復制
三、常量操作
|   ICONST_n (−1 ≤ 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 b, −128 ≤ b < 127  |  
             ...  |  
             ... , b 將byte常量入棧  |  
          
|   SIPUSH s, −32768 ≤ 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
}
四、算術和邏輯操作指令
|   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; | 
