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