JVM指令

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è)局部變量加載到操作棧 :
    iload iload_<n>
    fload fload_<n>
    lload lload_<n>
    dload dload_<n>
    aload aload_<n>
  • 將一個(gè)數(shù)值從操作數(shù)棧存儲(chǔ)到局部變量表
    istore istore_n
    fstore fstore_n
    lstore lstore_n
    dstore dstore_n
    astore astore_n
  • 將一個(gè)常量加載到操作數(shù)棧
    bipush sipush
    ldc ldc_w ldc2_w
    aconst_null iconst_ml iconst_<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)算指令

  • 加法指令
    iadd ladd fadd dadd
  • 減法指令
    isub lsub fsub dsub
  • 乘法指令
    imul lmul fmul dmul
  • 除法指令
    idiv ldiv fdiv ddiv
  • 求余指令
    irem lrem frem drem
  • 取反指令
    ineg lneg fneg dneg
  • 位移指令
    ishl ishr iushr lshl lshr lushr
  • 按位或指令
    ior lor
  • 按位與指令
    iand land
  • 按位異或指令
    ixor lxor
  • 局部變量自增指令
    iinc
  • 比較指令
    dcmpg dcmpl fcmpg fcmpl lcmp
  • 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)換 需要顯式指令 i2b i2c ....

對(duì)象創(chuàng)建與訪問指令

  • 創(chuàng)建類實(shí)例 new
  • 創(chuàng)建數(shù)組 newarray anewarray multianewarray
  • 訪問類字段 getfield putfield getstatic putstatic
  • 訪問數(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í)例的指令 instanceof checjcast

操作數(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)移指令

  • 條件分支 ifeq iflt ifle ...
  • 復(fù)合條件分支 tableswitch lookupswitch
  • 無條件分支 goto goto_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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java byte code 的學(xué)習(xí)意義 為啥要學(xué)java bytecode,這就跟你問我已經(jīng)會(huì)python了為...
    shanggl閱讀 1,868評(píng)論 0 3
  • 凡是帶const的表示將什么數(shù)據(jù)壓操作數(shù)棧 iconst_2 將int型數(shù)據(jù)2壓入到操作數(shù)棧; aconst_nu...
    LedBoot閱讀 3,415評(píng)論 1 8
  • Yes, it is as you guessed. The JVM/JRE uses Java bytecode...
    光劍書架上的書閱讀 5,916評(píng)論 1 15
  • 幸福是什么?在這個(gè)物欲橫流的社會(huì)里,很多人認(rèn)為幸福就是有很多很多的錢,豪宅美女,左擁右抱,如國(guó)民老公王思聰,炫富狂...
    心靈靜思閱讀 272評(píng)論 0 1
  • 我們班的朗讀者 朗讀是一個(gè)時(shí)髦的話題,繼一年級(jí)寒假開始了朗讀群,以后的很多天,我們都用聲音相逢在微信群。每天或是一...
    為為道來閱讀 646評(píng)論 0 2

友情鏈接更多精彩內(nèi)容