JVM 指令
指令由一個字節(jié)長度的,代表著某種特定操作含義的數(shù)字(操作碼)以及跟隨其后若干個代表此操作所需參數(shù)(操作數(shù))而構(gòu)成,大多數(shù)沒有操作數(shù);
操作碼的長度為1個字節(jié). 所以指令集的操作碼總數(shù)不超過256條
指令助記符是為了方便閱讀指令而語義化的一些符號
比如00000001的指令的助記符為iload;
字節(jié)碼與數(shù)據(jù)類型
分類
加載和存儲指令
指令助記符中 xxx_<n>是操作數(shù)為n時的xxx,他們省略掉了顯式的操作數(shù),不需要進行去操作數(shù)的動作,實際上操作數(shù)就隱含在指令中
-
將一個局部變量加載到操作棧 :
iloadiload_<n>
floadfload_<n>
lloadlload_<n>
dloaddload_<n>
aloadaload_<n> -
將一個數(shù)值從操作數(shù)棧存儲到局部變量表
istoreistore_n
fstorefstore_n
lstorelstore_n
dstoredstore_n
astoreastore_n -
將一個常量加載到操作數(shù)棧
bipushsipush
ldcldc_wldc2_w
aconst_nulliconst_mliconst_<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 //已經(jīng)沒有省略操作數(shù)的istore可用,所以用istore 4
9: ldc2_w #9 // double 44.1d 位于常量池
12: dstore 5
14: return
運算指令
-
加法指令
iaddladdfadddadd -
減法指令
isublsubfsubdsub -
乘法指令
imullmulfmuldmul -
除法指令
idivldivfdivddiv -
求余指令
iremlremfremdrem -
取反指令
ineglnegfnegdneg -
位移指令
ishlishriushrlshllshrlushr -
按位或指令
iorlor -
按位與指令
iand land -
按位異或指令
ixor lxor -
局部變量自增指令
iinc -
比較指令
dcmpgdcmplfcmpgfcmpllcmp - 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
類型裝換指令
-
寬化類型轉(zhuǎn)換 無須顯式指令 但是編譯之后也會出現(xiàn) 一個指令 比如
i2f -
窄化類型轉(zhuǎn)換 需要顯式指令
i2bi2c....
對象創(chuàng)建與訪問指令
-
創(chuàng)建類實例
new -
創(chuàng)建數(shù)組
newarrayanewarraymultianewarray -
訪問類字段
getfieldputfieldgetstaticputstatic -
訪問數(shù)組元素
b/c/s/i/l/f/d/a+aload -
將一個操作數(shù)棧存儲到數(shù)組元素的指令
b/c/s/i/f/d/a+astore -
獲取數(shù)組長度的指令
arraylength -
檢查類實例的指令
instanceofchecjcast
操作數(shù)棧管理指令
-
將操作數(shù)棧的棧頂一個或兩個元素出棧
pop pop2 -
復制棧頂一個或兩個數(shù)值并將復制或雙份的復制值重新壓入棧頂
dup dup2 dup_x1 dup2_x2 dup2_x2 -
將棧頂最頂端的兩個數(shù)值互換
swap
控制轉(zhuǎn)移指令
-
條件分支
ifeqifltifle... -
復合條件分支
tableswitchlookupswitch -
無條件分支
gotogoto_W
方法調(diào)用和返回指令
-
調(diào)用對象實例方法
invokevirtual -
調(diào)用接口方法
invokeinterface -
調(diào)用需要特殊處理的實例方法
invokespecial -
調(diào)用靜態(tài)方法
invokestatic -
運行時動態(tài)解析出調(diào)用點限定符所引的方法
invokedynamic
異常處理指令
-
顯式拋出異常
athrow - 運行時異常自動拋出
同步指令
-
持有管程
monitorenter -
釋放管程
monitorexit