<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0
    小注:去年在看《深入解析JVM》書的時候做的一些記錄,同時參考了《Java虛擬機規范》。只是對指令的一些列舉,加入了一些自己的理解。可以用來查詢。

    Java二進制指令代碼解析

    Java源碼在運行之前都要編譯成為字節碼格式(如.class文件),然后由ClassLoader將字節碼載入運行。在字節碼文件中,指令代碼只是其中的一部分,里面還記錄了字節碼文件的編譯版本、常量池、訪問權限、所有成員變量和成員方法等信息(詳見Java字節碼格式詳解)。本文主要簡單介紹不同Java指令的功能以及在代碼中如何解析二進制指令。 

    Java指令是基于棧的體系結構,大部分的指令默認的操作數在棧中。映像中ARM是基于寄存器的操作指令,而x86好像是混合寄存器和存儲器的,發現基于棧的操作指令確實簡單,學起來很快。不過不知道這種操作的效率怎么樣,以我自己的推測應該是不太好的。對這方面不太了解,隨便扯幾句。 

    Java總共有200多條指令,不過很多都是重復的。我的理解,網絡是Java一個非常重要的特性,而且Java在設計之初就認為字節碼是要在網絡中傳輸的,為了減少網絡傳輸流量,字節碼就要盡量設計精簡、緊湊。因而Java增加了很多重復指令,比如盡量減少操作數,因而我們會發現Java的很多指令都是沒有操作數的;并且指令中的操作數基本上都是當無法將值放到棧中的數據,比如局部變量的索引號和常量池中的索引號。 

    還有一點需要注意的是,在運行過程中,所有booleanbytecharshort都是以int類型值存在,因而對這些類型的指令操作很少。然而好像sun實現的虛擬機中。這些類型的數組據說不是以int類型的形式保存的,這個很奇怪。我的理解,以字對齊方式的操作效率會比較高,因而做了這種轉換,以空間換時間。 

    Java指令集(按功能分類)

    常量入棧指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    aconst_null

     

    null值入棧。

    iconst_m1

     

    -1(int)值入棧。

    iconst_0

     

    0(int)值入棧。

    iconst_1

     

    1(int)值入棧。

    iconst_2

     

    2(int)值入棧。

    iconst_3

     

    3(int)值入棧。

    iconst_4

     

    4(int)值入棧。

    iconst_5

     

    5(int)值入棧。

    lconst_0

     

    0(long)值入棧。

    lconst_1

     

    1(long)值入棧。

    fconst_0

     

    0(float)值入棧。

    fconst_1

     

    1(float)值入棧。

    fconst_2

     

    2(float)值入棧。

    dconst_0

     

    0(double)值入棧。

    dconst_1

     

    1(double)值入棧。

    bipush

    valuebyte

    valuebyte值帶符號擴展成int值入棧。

    sipush

    valuebyte1

    valuebyte2

    (valuebyte1 << 8) | valuebyte2 值帶符號擴展成int值入棧。

    ldc

    indexbyte1

    常量池中的常量值(int, float, string reference, object reference)入棧。

    ldc_w

    indexbyte1

    indexbyte2

    常量池中常量(int, float, string reference, object reference)入棧。

    ldc2_w

    indexbyte1

    indexbyte2

    常量池中常量(long, double)入棧。

     

    局部變量值轉載到棧中指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    (wide)aload

    indexbyte

    從局部變量indexbyte中裝載引用類型值入棧。

    aload_0

     

    從局部變量0中裝載引用類型值入棧。

    aload_1

     

    從局部變量1中裝載引用類型值入棧。

    aload_2

     

    從局部變量2中裝載引用類型值入棧。

    aload_3

     

    從局部變量3中裝載引用類型值入棧。

    (wide)iload

    indexbyte

    從局部變量indexbyte中裝載int類型值入棧。

    iload_0

     

    從局部變量0中裝載int類型值入棧。

    iload_1

     

    從局部變量1中裝載int類型值入棧。

    iload_2

     

    從局部變量2中裝載int類型值入棧。

    iload_3

     

    從局部變量3中裝載int類型值入棧。

    (wide)lload

    indexbyte

    從局部變量indexbyte中裝載long類型值入棧。

    lload_0

     

    從局部變量0中裝載int類型值入棧。

    lload_1

     

    從局部變量1中裝載int類型值入棧。

    lload_2

     

    從局部變量2中裝載int類型值入棧。

    lload_3

     

    從局部變量3中裝載int類型值入棧。

    (wide)fload

    indexbyte

    從局部變量indexbyte中裝載float類型值入棧。

    fload_0

     

    從局部變量0中裝載float類型值入棧。

    fload_1

     

    從局部變量1中裝載float類型值入棧。

    fload_2

     

    從局部變量2中裝載float類型值入棧。

    fload_3

     

    從局部變量3中裝載float類型值入棧。

    (wide)dload

    indexbyte

    從局部變量indexbyte中裝載double類型值入棧。

    dload_0

     

    從局部變量0中裝載double類型值入棧。

    dload_1

     

    從局部變量1中裝載double類型值入棧。

    dload_2

     

    從局部變量2中裝載double類型值入棧。

    dload_3

     

    從局部變量3中裝載double類型值入棧。

    aaload

     

    從引用類型數組中裝載指定項的值。

    iaload

     

    int類型數組中裝載指定項的值。

    laload

     

    long類型數組中裝載指定項的值。

    faload

     

    float類型數組中裝載指定項的值。

    daload

     

    double類型數組中裝載指定項的值。

    baload

     

    boolean類型數組或byte類型數組中裝載指定項的值(先轉換為int類型值,后壓棧)。

    caload

     

    char類型數組中裝載指定項的值(先轉換為int類型值,后壓棧)。

    saload

     

    short類型數組中裝載指定項的值(先轉換為int類型值,后壓棧)。

     

    將棧頂值保存到局部變量中指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    (wide)astore

    indexbyte

    將棧頂引用類型值保存到局部變量indexbyte中。

    astroe_0

     

    將棧頂引用類型值保存到局部變量0中。

    astore_1

     

    將棧頂引用類型值保存到局部變量1中。

    astore_2

     

    將棧頂引用類型值保存到局部變量2中。

    astore_3

     

    將棧頂引用類型值保存到局部變量3中。

    (wide)istore

    indexbyte

    將棧頂int類型值保存到局部變量indexbyte中。

    istore_0

     

    將棧頂int類型值保存到局部變量0中。

    istore_1

     

    將棧頂int類型值保存到局部變量1中。

    istore_2

     

    將棧頂int類型值保存到局部變量2中。

    istore_3

     

    將棧頂int類型值保存到局部變量3中。

    (wide)lstore

    indexbyte

    將棧頂long類型值保存到局部變量indexbyte中。

    lstore_0

     

    將棧頂long類型值保存到局部變量0中。

    lstore_1

     

    將棧頂long類型值保存到局部變量1中。

    lstore_2

     

    將棧頂long類型值保存到局部變量2中。

    lstroe_3

     

    將棧頂long類型值保存到局部變量3中。

    (wide)fstore

    indexbyte

    將棧頂float類型值保存到局部變量indexbyte中。

    fstore_0

     

    將棧頂float類型值保存到局部變量0中。

    fstore_1

     

    將棧頂float類型值保存到局部變量1中。

    fstore_2

     

    將棧頂float類型值保存到局部變量2中。

    fstore_3

     

    將棧頂float類型值保存到局部變量3中。

    (wide)dstore

    indexbyte

    將棧頂double類型值保存到局部變量indexbyte中。

    dstore_0

     

    將棧頂double類型值保存到局部變量0中。

    dstore_1

     

    將棧頂double類型值保存到局部變量1中。

    dstore_2

     

    將棧頂double類型值保存到局部變量2中。

    dstore_3

     

    將棧頂double類型值保存到局部變量3中。

    aastore

     

    將棧頂引用類型值保存到指定引用類型數組的指定項。

    iastore

     

    將棧頂int類型值保存到指定int類型數組的指定項。

    lastore

     

    將棧頂long類型值保存到指定long類型數組的指定項。

    fastore

     

    將棧頂float類型值保存到指定float類型數組的指定項。

    dastore

     

    將棧頂double類型值保存到指定double類型數組的指定項。

    bastroe

     

    將棧頂boolean類型值或byte類型值保存到指定boolean類型數組或byte類型數組的指定項。

    castore

     

    將棧頂char類型值保存到指定char類型數組的指定項。

    sastore

     

    將棧頂short類型值保存到指定short類型數組的指定項。

     

    wide指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    wide

     

    使用附加字節擴展局部變量索引(iinc指令特殊)。

     

    通用(無類型)棧操作指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    nop

     

    空操作。

    pop

     

    從棧頂彈出一個字長的數據。

    pop2

     

    從棧頂彈出兩個字長的數據。

    dup

     

    復制棧頂一個字長的數據,將復制后的數據壓棧。

    dup_x1

     

    復制棧頂一個字長的數據,彈出棧頂兩個字長數據,先將復制后的數據壓棧,再將彈出的兩個字長數據壓棧。

    dup_x2

     

    復制棧頂一個字長的數據,彈出棧頂三個字長的數據,將復制后的數據壓棧,再將彈出的三個字長的數據壓棧。

    dup2

     

    復制棧頂兩個字長的數據,將復制后的兩個字長的數據壓棧。

    dup2_x1

     

    復制棧頂兩個字長的數據,彈出棧頂三個字長的數據,將復制后的兩個字長的數據壓棧,再將彈出的三個字長的數據壓棧。

    dup2_x2

     

    復制棧頂兩個字長的數據,彈出棧頂四個字長的數據,將復制后的兩個字長的數據壓棧,再將彈出的四個字長的數據壓棧。

    swap

     

    交換棧頂兩個字長的數據的位置。Java指令中沒有提供以兩個字長為單位的交換指令。

     

    類型轉換指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    i2f

     

    將棧頂int類型值轉換為float類型值。

    i2l

     

    將棧頂int類型值轉換為long類型值。

    i2d

     

    將棧頂int類型值轉換為double類型值。

    f2i

     

    將棧頂float類型值轉換為int類型值。

    f2l

     

    將棧頂float類型值轉換為long類型值。

    f2d

     

    將棧頂float類型值轉換為double類型值。

    l2i

     

    將棧頂long類型值轉換為int類型值。

    l2f

     

    將棧頂long類型值轉換為float類型值。

    l2d

     

    將棧頂long類型值轉換double類型值。

    d2i

     

    將棧頂double類型值轉換為int類型值。

    d2f

     

    將棧頂double類型值轉換為float類型值。

    d2l

     

    將棧頂double類型值轉換為long類型值。

    i2b

     

    將棧頂int類型值截斷成byte類型,后帶符號擴展成int類型值入棧。

    i2c

     

    將棧頂int類型值截斷成char類型值,后帶符號擴展成int類型值入棧。

    i2s

     

    將棧頂int類型值截斷成short類型值,后帶符號擴展成int類型值入棧。

     

    整數運算

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    iadd

     

    將棧頂兩int類型數相加,結果入棧。

    isub

     

    將棧頂兩int類型數相減,結果入棧。

    imul

     

    將棧頂兩int類型數相乘,結果入棧。

    idiv

     

    將棧頂兩int類型數相除,結果入棧。

    irem

     

    將棧頂兩int類型數取模,結果入棧。

    ineg

     

    將棧頂int類型值取負,結果入棧。

    ladd

     

    將棧頂兩long類型數相加,結果入棧。

    lsub

     

    將棧頂兩long類型數相減,結果入棧。

    lmul

     

    將棧頂兩long類型數相乘,結果入棧。

    ldiv

     

    將棧頂兩long類型數相除,結果入棧。

    lrem

     

    將棧頂兩long類型數取模,結果入棧。

    lneg

     

    將棧頂long類型值取負,結果入棧。

    (wide)iinc

    indexbyte

    constbyte

    將整數值constbyte加到indexbyte指定的int類型的局部變量中。

     

    浮點運算

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    fadd

     

    將棧頂兩float類型數相加,結果入棧。

    fsub

     

    將棧頂兩float類型數相減,結果入棧。

    fmul

     

    將棧頂兩float類型數相乘,結果入棧。

    fdiv

     

    將棧頂兩float類型數相除,結果入棧。

    frem

     

    將棧頂兩float類型數取模,結果入棧。

    fneg

     

    將棧頂float類型值取反,結果入棧。

    dadd

     

    將棧頂兩double類型數相加,結果入棧。

    dsub

     

    將棧頂兩double類型數相減,結果入棧。

    dmul

     

    將棧頂兩double類型數相乘,結果入棧。

    ddiv

     

    將棧頂兩double類型數相除,結果入棧。

    drem

     

    將棧頂兩double類型數取模,結果入棧。

    dneg

     

    將棧頂double類型值取負,結果入棧。

     

    邏輯運算——移位運算

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    ishl

     

    左移int類型值。

    lshl

     

    左移long類型值。

    ishr

     

    算術右移int類型值。

    lshr

     

    算術右移long類型值。

    iushr

     

    邏輯右移int類型值。

    lushr

     

    邏輯右移long類型值。

     

    邏輯運算——按位布爾運算

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    iand

     

    int類型按位與運算。

    land

     

    long類型的按位與運算。

    ior

     

    int類型的按位或運算。

    lor

     

    long類型的按位或運算。

    ixor

     

    int類型的按位異或運算。

    lxor

     

    long類型的按位異或運算。

     

    控制流指令——條件跳轉指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    ifeq

    branchbyte1

    branchbyte2

    若棧頂int類型值為0則跳轉。

    ifne

    branchbyte1

    branchbyte2

    若棧頂int類型值不為0則跳轉。

    iflt

    branchbyte1

    branchbyte2

    若棧頂int類型值小于0則跳轉。

    ifle

    branchbyte1

    branchbyte2

    若棧頂int類型值小于等于0則跳轉。

    ifgt

    branchbyte1

    branchbyte2

    若棧頂int類型值大于0則跳轉。

    ifge

    branchbyte1

    branchbyte2

    若棧頂int類型值大于等于0則跳轉。

    if_icmpeq

    branchbyte1

    branchbyte2

    若棧頂兩int類型值相等則跳轉。

    if_icmpne

    branchbyte1

    branchbyte2

    若棧頂兩int類型值不相等則跳轉。

    if_icmplt

    branchbyte1

    branchbyte2

    若棧頂兩int類型值前小于后則跳轉。

    if_icmple

    branchbyte1

    branchbyte2

    若棧頂兩int類型值前小于等于后則跳轉。

    if_icmpgt

    branchbyte1

    branchbyte2

    若棧頂兩int類型值前大于后則跳轉。

    if_icmpge

    branchbyte1

    branchbyte2

    若棧頂兩int類型值前大于等于后則跳轉。

    ifnull

    branchbyte1

    branchbyte2

    若棧頂引用值為null則跳轉。

    ifnonnull

    branchbyte1

    branchbyte2

    若棧頂引用值不為null則跳轉。

    if_acmpeq

    branchbyte1

    branchbyte2

    若棧頂兩引用類型值相等則跳轉。

    if_acmpne

    branchbyte1

    branchbyte2

    若棧頂兩引用類型值不相等則跳轉。

     

    控制流指令——比較指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    lcmp

     

    比較棧頂兩long類型值,前者大,1入棧;相等,0入棧;后者大,-1入棧。

    fcmpl

     

    比較棧頂兩float類型值,前者大,1入棧;相等,0入棧;后者大,-1入棧;有NaN存在,-1入棧。

    fcmpg

     

    比較棧頂兩float類型值,前者大,1入棧;相等,0入棧;后者大,-1入棧;有NaN存在,-1入棧。

    dcmpl

     

    比較棧頂兩double類型值,前者大,1入棧;相等,0入棧;后者大,-1入棧;有NaN存在,-1入棧。

    dcmpg

     

    比較棧頂兩double類型值,前者大,1入棧;相等,0入棧;后者大,-1入棧;有NaN存在,-1入棧。

     

    控制流指令——無條件跳轉指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    goto

    branchbyte1

    branchbyte2

    無條件跳轉到指定位置。

    goto_w

    branchbyte1

    branchbyte2

    branchbyte3

    branchbyte4

    無條件跳轉到指定位置(寬索引)。

     

    控制流指令——表跳轉指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    tableswitch

    <0-3bytepad>

    defaultbyte1

    defaultbyte2

    defaultbyte3

    defaultbyte4

    lowbyte1

    lowbyte2

    lowbyte3

    lowbyte4

    highbyte1

    highbyte2

    highbyte3

    highbyte4

    jump offsets...

    通過索引訪問跳轉表,并跳轉。

    lookupswitch

    <0-3bytepad>

    defaultbyte1

    defaultbyte2

    defaultbyte3

    defaultbyte4

    npairs1

    npairs2

    npairs3

    npairs4

    match offsets

    通過鍵值訪問跳轉表,并跳轉。

     

    控制流指令——異常和finally

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    athrow

     

    拋出異常。

    jsr

    branchbyte1

    branchbyte2

    跳轉到子例程序。

    jsr_w

    branchbyte1

    branchbyte2

    branchbyte3

    branchbyte4

    跳轉到子例程序(寬索引)。

    (wide)ret

    indexbyte

    返回子例程序。

     

    對象操作指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    new

    indexbyte1

    indexbyte2

    創建新的對象實例。

    checkcast

    indexbyte1

    indexbyte

    類型強轉。

    instanceof

    indexbyte1

    indexbyte2

    判斷類型。

    getfield

    indexbyte1

    indexbyte2

    獲取對象字段的值。

    putfield

    indexbyte1

    indexbyte2

    給對象字段賦值。

    getstatic

    indexbyte1

    indexbyte2

    獲取靜態字段的值。

    putstatic

    indexbyte1

    indexbyte2

    給靜態字段賦值。

     

    數組操作指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    newarray

    atype

    創建type類型的數組。

    anewarray

    indexbyte1

    indexbyte2

    創建引用類型的數組。

    arraylength

     

    獲取一維數組的長度。

    multianewarray

    indexbyte1

    indexbyte2

    dimension

    創建dimension維度的數組。

     

    方法調用指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    invokespecial

    indexbyte1

    indexbyte2

    編譯時方法綁定調用方法。

    invokevirtual

    indexbyte1

    indexbyte2

    運行時方法綁定調用方法。

    invokestatic

    indexbyte1

    indexbyte2

    調用靜態方法。

    invokeinterface

    indexbyte1

    indexbyte2

    count

    0

    調用接口方法。

     

    方法返回指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    ireturn

     

    返回int類型值。

    lreturn

     

    返回long類型值。

    freturn

     

    返回float類型值。

    dreturn

     

    返回double類型值。

    areturn

     

    返回引用類型值。

    return

     

    void函數返回。

     

    線程同步指令

    操作碼(助記符)

    操作數

    描述(棧指操作數棧)

    monitorenter

     

    進入并獲得對象監視器。

    monitorexit

     

    釋放并退出對象監視器。

    參考《深入解析JVM》 2010年10月6日

    posted on 2011-09-13 00:03 DLevin 閱讀(6835) 評論(1)  編輯  收藏 所屬分類: 深入JVM

    FeedBack:
    # re: Java二進制指令代碼解析
    2011-09-13 09:04 | tb
    好東西 收藏了   回復  更多評論
      
    主站蜘蛛池模板: 久久精品a亚洲国产v高清不卡 | 久久国产亚洲电影天堂| 亚洲精品无码久久久久去q | 亚洲人成网站在线播放影院在线| 久久亚洲私人国产精品vA| 2020天堂在线亚洲精品专区| 亚洲变态另类一区二区三区| 免费一级全黄少妇性色生活片| 成人A毛片免费观看网站| 亚洲gay片在线gv网站| 一级做a爰性色毛片免费| 无码精品一区二区三区免费视频| 国产卡二卡三卡四卡免费网址| 国产大片51精品免费观看| 亚洲乱码无码永久不卡在线| 亚洲性色高清完整版在线观看| 久久无码av亚洲精品色午夜| 丝袜捆绑调教视频免费区| 无码国产精品一区二区免费式影视 | 国产91精品一区二区麻豆亚洲| 亚洲制服中文字幕第一区| 亚洲精品9999久久久久无码| 国产午夜无码片免费| 黄色片在线免费观看| 国产成人亚洲精品狼色在线| 亚洲欧洲日产韩国在线| 黄人成a动漫片免费网站| 91福利免费体验区观看区| 国产成人免费一区二区三区| 久久精品亚洲视频| 久久亚洲精品11p| 人妻无码久久一区二区三区免费| 国产成人免费a在线视频色戒| 亚洲欧洲在线观看| 日韩毛片免费一二三| 4虎永免费最新永久免费地址| 伊人久久精品亚洲午夜| 亚洲精品GV天堂无码男同| 日韩内射激情视频在线播放免费 | 亚洲 自拍 另类小说综合图区| 亚洲男人天堂影院|