JVM 指令

 

字节码

 

  enum Code {
    _illegal              =  -1,

    // Java bytecodes
    _nop                  =   0, // 0x00
    _aconst_null          =   1, // 0x01
    _iconst_m1            =   2, // 0x02
    _iconst_0             =   3, // 0x03
    _iconst_1             =   4, // 0x04
    _iconst_2             =   5, // 0x05
    _iconst_3             =   6, // 0x06
    _iconst_4             =   7, // 0x07
    _iconst_5             =   8, // 0x08
    _lconst_0             =   9, // 0x09
    _lconst_1             =  10, // 0x0a
    _fconst_0             =  11, // 0x0b
    _fconst_1             =  12, // 0x0c
    _fconst_2             =  13, // 0x0d
    _dconst_0             =  14, // 0x0e
    _dconst_1             =  15, // 0x0f
    _bipush               =  16, // 0x10
    _sipush               =  17, // 0x11
    _ldc                  =  18, // 0x12
    _ldc_w                =  19, // 0x13
    _ldc2_w               =  20, // 0x14
    _iload                =  21, // 0x15
    _lload                =  22, // 0x16
    _fload                =  23, // 0x17
    _dload                =  24, // 0x18
    _aload                =  25, // 0x19
    _iload_0              =  26, // 0x1a
    _iload_1              =  27, // 0x1b
    _iload_2              =  28, // 0x1c
    _iload_3              =  29, // 0x1d
    _lload_0              =  30, // 0x1e
    _lload_1              =  31, // 0x1f
    _lload_2              =  32, // 0x20
    _lload_3              =  33, // 0x21
    _fload_0              =  34, // 0x22
    _fload_1              =  35, // 0x23
    _fload_2              =  36, // 0x24
    _fload_3              =  37, // 0x25
    _dload_0              =  38, // 0x26
    _dload_1              =  39, // 0x27
    _dload_2              =  40, // 0x28
    _dload_3              =  41, // 0x29
    _aload_0              =  42, // 0x2a
    _aload_1              =  43, // 0x2b
    _aload_2              =  44, // 0x2c
    _aload_3              =  45, // 0x2d
    _iaload               =  46, // 0x2e
    _laload               =  47, // 0x2f
    _faload               =  48, // 0x30
    _daload               =  49, // 0x31
    _aaload               =  50, // 0x32
    _baload               =  51, // 0x33
    _caload               =  52, // 0x34
    _saload               =  53, // 0x35
    _istore               =  54, // 0x36
    _lstore               =  55, // 0x37
    _fstore               =  56, // 0x38
    _dstore               =  57, // 0x39
    _astore               =  58, // 0x3a
    _istore_0             =  59, // 0x3b
    _istore_1             =  60, // 0x3c
    _istore_2             =  61, // 0x3d
    _istore_3             =  62, // 0x3e
    _lstore_0             =  63, // 0x3f
    _lstore_1             =  64, // 0x40
    _lstore_2             =  65, // 0x41
    _lstore_3             =  66, // 0x42
    _fstore_0             =  67, // 0x43
    _fstore_1             =  68, // 0x44
    _fstore_2             =  69, // 0x45
    _fstore_3             =  70, // 0x46
    _dstore_0             =  71, // 0x47
    _dstore_1             =  72, // 0x48
    _dstore_2             =  73, // 0x49
    _dstore_3             =  74, // 0x4a
    _astore_0             =  75, // 0x4b
    _astore_1             =  76, // 0x4c
    _astore_2             =  77, // 0x4d
    _astore_3             =  78, // 0x4e
    _iastore              =  79, // 0x4f
    _lastore              =  80, // 0x50
    _fastore              =  81, // 0x51
    _dastore              =  82, // 0x52
    _aastore              =  83, // 0x53
    _bastore              =  84, // 0x54
    _castore              =  85, // 0x55
    _sastore              =  86, // 0x56
    _pop                  =  87, // 0x57
    _pop2                 =  88, // 0x58
    _dup                  =  89, // 0x59
    _dup_x1               =  90, // 0x5a
    _dup_x2               =  91, // 0x5b
    _dup2                 =  92, // 0x5c
    _dup2_x1              =  93, // 0x5d
    _dup2_x2              =  94, // 0x5e
    _swap                 =  95, // 0x5f
    _iadd                 =  96, // 0x60
    _ladd                 =  97, // 0x61
    _fadd                 =  98, // 0x62
    _dadd                 =  99, // 0x63
    _isub                 = 100, // 0x64
    _lsub                 = 101, // 0x65
    _fsub                 = 102, // 0x66
    _dsub                 = 103, // 0x67
    _imul                 = 104, // 0x68
    _lmul                 = 105, // 0x69
    _fmul                 = 106, // 0x6a
    _dmul                 = 107, // 0x6b
    _idiv                 = 108, // 0x6c
    _ldiv                 = 109, // 0x6d
    _fdiv                 = 110, // 0x6e
    _ddiv                 = 111, // 0x6f
    _irem                 = 112, // 0x70
    _lrem                 = 113, // 0x71
    _frem                 = 114, // 0x72
    _drem                 = 115, // 0x73
    _ineg                 = 116, // 0x74
    _lneg                 = 117, // 0x75
    _fneg                 = 118, // 0x76
    _dneg                 = 119, // 0x77
    _ishl                 = 120, // 0x78
    _lshl                 = 121, // 0x79
    _ishr                 = 122, // 0x7a
    _lshr                 = 123, // 0x7b
    _iushr                = 124, // 0x7c
    _lushr                = 125, // 0x7d
    _iand                 = 126, // 0x7e
    _land                 = 127, // 0x7f
    _ior                  = 128, // 0x80
    _lor                  = 129, // 0x81
    _ixor                 = 130, // 0x82
    _lxor                 = 131, // 0x83
    _iinc                 = 132, // 0x84
    _i2l                  = 133, // 0x85
    _i2f                  = 134, // 0x86
    _i2d                  = 135, // 0x87
    _l2i                  = 136, // 0x88
    _l2f                  = 137, // 0x89
    _l2d                  = 138, // 0x8a
    _f2i                  = 139, // 0x8b
    _f2l                  = 140, // 0x8c
    _f2d                  = 141, // 0x8d
    _d2i                  = 142, // 0x8e
    _d2l                  = 143, // 0x8f
    _d2f                  = 144, // 0x90
    _i2b                  = 145, // 0x91
    _i2c                  = 146, // 0x92
    _i2s                  = 147, // 0x93
    _lcmp                 = 148, // 0x94
    _fcmpl                = 149, // 0x95
    _fcmpg                = 150, // 0x96
    _dcmpl                = 151, // 0x97
    _dcmpg                = 152, // 0x98
    _ifeq                 = 153, // 0x99
    _ifne                 = 154, // 0x9a
    _iflt                 = 155, // 0x9b
    _ifge                 = 156, // 0x9c
    _ifgt                 = 157, // 0x9d
    _ifle                 = 158, // 0x9e
    _if_icmpeq            = 159, // 0x9f
    _if_icmpne            = 160, // 0xa0
    _if_icmplt            = 161, // 0xa1
    _if_icmpge            = 162, // 0xa2
    _if_icmpgt            = 163, // 0xa3
    _if_icmple            = 164, // 0xa4
    _if_acmpeq            = 165, // 0xa5
    _if_acmpne            = 166, // 0xa6
    _goto                 = 167, // 0xa7
    _jsr                  = 168, // 0xa8
    _ret                  = 169, // 0xa9
    _tableswitch          = 170, // 0xaa
    _lookupswitch         = 171, // 0xab
    _ireturn              = 172, // 0xac
    _lreturn              = 173, // 0xad
    _freturn              = 174, // 0xae
    _dreturn              = 175, // 0xaf
    _areturn              = 176, // 0xb0
    _return               = 177, // 0xb1
    _getstatic            = 178, // 0xb2
    _putstatic            = 179, // 0xb3
    _getfield             = 180, // 0xb4
    _putfield             = 181, // 0xb5
    _invokevirtual        = 182, // 0xb6
    _invokespecial        = 183, // 0xb7
    _invokestatic         = 184, // 0xb8
    _invokeinterface      = 185, // 0xb9
    _invokedynamic        = 186, // 0xba     // if EnableInvokeDynamic
    _new                  = 187, // 0xbb
    _newarray             = 188, // 0xbc
    _anewarray            = 189, // 0xbd
    _arraylength          = 190, // 0xbe
    _athrow               = 191, // 0xbf
    _checkcast            = 192, // 0xc0
    _instanceof           = 193, // 0xc1
    _monitorenter         = 194, // 0xc2
    _monitorexit          = 195, // 0xc3
    _wide                 = 196, // 0xc4
    _multianewarray       = 197, // 0xc5
    _ifnull               = 198, // 0xc6
    _ifnonnull            = 199, // 0xc7
    _goto_w               = 200, // 0xc8
    _jsr_w                = 201, // 0xc9
    _breakpoint           = 202, // 0xca

    number_of_java_codes,

    // JVM bytecodes
    _fast_agetfield       = number_of_java_codes,
    _fast_bgetfield       ,
    _fast_cgetfield       ,
    _fast_dgetfield       ,
    _fast_fgetfield       ,
    _fast_igetfield       ,
    _fast_lgetfield       ,
    _fast_sgetfield       ,

    _fast_aputfield       ,
    _fast_bputfield       ,
    _fast_zputfield       ,
    _fast_cputfield       ,
    _fast_dputfield       ,
    _fast_fputfield       ,
    _fast_iputfield       ,
    _fast_lputfield       ,
    _fast_sputfield       ,

    _fast_aload_0         ,
    _fast_iaccess_0       ,
    _fast_aaccess_0       ,
    _fast_faccess_0       ,

    _fast_iload           ,
    _fast_iload2          ,
    _fast_icaload         ,

    _fast_invokevfinal    ,
    _fast_linearswitch    ,
    _fast_binaryswitch    ,

    // special handling of oop constants:
    _fast_aldc            ,
    _fast_aldc_w          ,

    _return_register_finalizer    ,

    _shouldnotreachhere,      // For debugging

    // Platform specific JVM bytecodes
#ifdef TARGET_ARCH_x86
# include "bytecodes_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytecodes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytecodes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytecodes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytecodes_ppc.hpp"
#endif


    number_of_codes
  };
将操作栈中的栈顶元素弹出并设值本地变量表对应的变量。
astore
astore_<n>
指令_astore,_astore_0,_astore_1,_astore_2,_astore_3
 
dstore
dstore_<n>
 
fstore
fstore_<n>
 
istore
istore_<n>
 
lstore
lstore_<n>
 
int i = 10;
long l = 100L;
float f = 0.1F;
double d = 0.1;
String s = "abc";
char c = 'a';
        0: bipush        10
       2: istore_1
       3: ldc2_w        #2                  // long 100l
       6: lstore_2
       7: ldc           #4                  // float 0.1f
       9: fstore        4
      11: ldc2_w        #5                  // double 0.1d
      14: dstore        5
      16: ldc           #7                  // String abc
      18: astore        7
      20: bipush        97
      22: istore        8
 
 
 
bastore
 
castore
 
dastore
 
fastore
 
iastore
 
lastore
 
sastore
 
将本地变量表中对应的变量压入到操作栈中。
aload
aload_<n>
指令_aload_0,_aload_1,_aload_2,_aload_3,_fast_aload_0
 
dload
dload_<n>
 
fload
fload_<n>
 
iload
iload_<n>
 
lload
lload_<n>
 
aaload
 
baload
 
caload
 
daload
 
faload
 
iaload
 
laload
 
saload
int i2 = i;
long l2 = l;
float f2 = f;
double d2 = d;
String s2 = s;
char c2 = c;
 
      24: iload_1
      25: istore        9
      27: lload_2
      28: lstore        10
      30: fload         4
      32: fstore        12
      34: dload         5
      36: dstore        13
      38: aload         7
      40: astore        15
      42: iload         8
      44: istore        16
 
创建对象new例子:
new
public class JavaNew {

	public static void main(String[] args) {
		Object obj = new Object();
	}
}
反汇编结果:
>javap -c JavaNew
Compiled from "JavaNew.java"
public class JavaNew {
  public JavaNew();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return
 
  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/Object
       3: dup
       4: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       7: astore_1
       8: return
}
从反编译的结果看,生成了一个构造方法,源代码中我没有为JavaNew定义任何构造方法,如果没有显式定义构造方法,Java会隐式定义一个默认的无参构造方法。在public JavaNew();下面是这个构造方法的字节码实现指令,其中一条重要的指令:invokespecial #1,在JVM解释执行遇到这个指令的时候,JVM会调用一个特殊方法:<init>,这从后面的注释也可以看出来:// Method java/lang/Object."<init>":()V,它对应Java层面的构造方法:public JavaNew() {},在这里我们可以认为构造方法也是一个特殊的构造方法,特殊在于在Java层面上它的方法名在Java层面看和类型一样,但在JVM层面却对应的是:<init>,另外没有显式的返回类型,只有参数类型是一样的。最后要注意的事后面的()V,它是构造方法的签名,其形式如下:
(参数类型签名列表)返回类型签名
在另一篇文章: https://lobin.iteye.com/blog/2437928,讲GetMethodID函数的时候也会传入对应方法的签名。
创建数组newarray例子:
newarray
public class JavaNewArray {

	public static void main(String[] args) {
		int test[] = new int[123];
	}
}
 反汇编结果:
>javap -c JavaNewArray
Compiled from "JavaNewArray.java"
public class JavaNewArray {
  public JavaNewArray();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        123
       2: newarray       int
       4: astore_1
       5: return
}
 ldc指令
将运行时常量池中的item压入到操作栈。
String str = "string abc";
        0: ldc           #2                  // String string abc
       2: astore_1
 
String str = new String("string abc");
 
       0: new           #2                  // class java/lang/String
       3: dup
       4: ldc           #3                  // String string abc
       6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
       9: astore_1
在这个例子中,将字符串"string abc"压入到操作栈。
 
iconst_<i>指令
将int常量i压入操作栈。如iconst_m1 = 2 (0x2), iconst_0 = 3 (0x3), iconst_1 = 4 (0x4), iconst_2 = 5 (0x5), iconst_3 = 6 (0x6), iconst_4 = 7 (0x7), iconst_5 = 8 (0x8)分别表示将-1, 0, 1, 2, 3, 4, 5压入操作栈。
       5: iconst_1
 
类加载时,在验证阶段针对指令的类型检查,参考 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.9,其中列举了所有在验证阶段会进行针对指令的类型检查。aaload、aastore、aconst_null、aload, aload_<n>、anewarray、areturn、arraylength、astore, astore_<n>、athrow等.
 
在以下例子中:
public class VariableSetTest {

    private int value;

    public static void main(String[] args) {
        VariableSetTest test = new VariableSetTest();


        test.value++;
        System.out.println(test.value);
    }
}
 public class VariableSetTest {
  public VariableSetTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
 
  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class VariableSetTest
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: dup
      10: getfield      #4                  // Field value:I
      13: iconst_1
      14: iadd
      15: putfield      #4                  // Field value:I
      18: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      21: aload_1
      22: getfield      #4                  // Field value:I
      25: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V
      28: return
}
public class VariableSetTest2 {

    public static void main(String[] args) {
        int value = 0;
        value++;
        System.out.println(value);
    }
}
 public class VariableSetTest2 {
  public VariableSetTest2();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
 
  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iinc          1, 1
       5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       8: iload_1
       9: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      12: return
}
1、VariableSetTest中的++操作对应的指令为14: iadd,但 VariableSetTest2中的++操作对应的指令为 2: iinc          1, 1。
2、 VariableSetTest, VariableSetTest2中的++操作会更新value的值,但在反编译后的指令码中没有astore类似的指令更新本地变量表中对应变量value的值。

 

字节码
  enum Code {
    _illegal              =  -1,

    // Java bytecodes
    _nop                  =   0, // 0x00
    _aconst_null          =   1, // 0x01
    _iconst_m1            =   2, // 0x02
    _iconst_0             =   3, // 0x03
    _iconst_1             =   4, // 0x04
    _iconst_2             =   5, // 0x05
    _iconst_3             =   6, // 0x06
    _iconst_4             =   7, // 0x07
    _iconst_5             =   8, // 0x08
    _lconst_0             =   9, // 0x09
    _lconst_1             =  10, // 0x0a
    _fconst_0             =  11, // 0x0b
    _fconst_1             =  12, // 0x0c
    _fconst_2             =  13, // 0x0d
    _dconst_0             =  14, // 0x0e
    _dconst_1             =  15, // 0x0f
    _bipush               =  16, // 0x10
    _sipush               =  17, // 0x11
    _ldc                  =  18, // 0x12
    _ldc_w                =  19, // 0x13
    _ldc2_w               =  20, // 0x14
    _iload                =  21, // 0x15
    _lload                =  22, // 0x16
    _fload                =  23, // 0x17
    _dload                =  24, // 0x18
    _aload                =  25, // 0x19
    _iload_0              =  26, // 0x1a
    _iload_1              =  27, // 0x1b
    _iload_2              =  28, // 0x1c
    _iload_3              =  29, // 0x1d
    _lload_0              =  30, // 0x1e
    _lload_1              =  31, // 0x1f
    _lload_2              =  32, // 0x20
    _lload_3              =  33, // 0x21
    _fload_0              =  34, // 0x22
    _fload_1              =  35, // 0x23
    _fload_2              =  36, // 0x24
    _fload_3              =  37, // 0x25
    _dload_0              =  38, // 0x26
    _dload_1              =  39, // 0x27
    _dload_2              =  40, // 0x28
    _dload_3              =  41, // 0x29
    _aload_0              =  42, // 0x2a
    _aload_1              =  43, // 0x2b
    _aload_2              =  44, // 0x2c
    _aload_3              =  45, // 0x2d
    _iaload               =  46, // 0x2e
    _laload               =  47, // 0x2f
    _faload               =  48, // 0x30
    _daload               =  49, // 0x31
    _aaload               =  50, // 0x32
    _baload               =  51, // 0x33
    _caload               =  52, // 0x34
    _saload               =  53, // 0x35
    _istore               =  54, // 0x36
    _lstore               =  55, // 0x37
    _fstore               =  56, // 0x38
    _dstore               =  57, // 0x39
    _astore               =  58, // 0x3a
    _istore_0             =  59, // 0x3b
    _istore_1             =  60, // 0x3c
    _istore_2             =  61, // 0x3d
    _istore_3             =  62, // 0x3e
    _lstore_0             =  63, // 0x3f
    _lstore_1             =  64, // 0x40
    _lstore_2             =  65, // 0x41
    _lstore_3             =  66, // 0x42
    _fstore_0             =  67, // 0x43
    _fstore_1             =  68, // 0x44
    _fstore_2             =  69, // 0x45
    _fstore_3             =  70, // 0x46
    _dstore_0             =  71, // 0x47
    _dstore_1             =  72, // 0x48
    _dstore_2             =  73, // 0x49
    _dstore_3             =  74, // 0x4a
    _astore_0             =  75, // 0x4b
    _astore_1             =  76, // 0x4c
    _astore_2             =  77, // 0x4d
    _astore_3             =  78, // 0x4e
    _iastore              =  79, // 0x4f
    _lastore              =  80, // 0x50
    _fastore              =  81, // 0x51
    _dastore              =  82, // 0x52
    _aastore              =  83, // 0x53
    _bastore              =  84, // 0x54
    _castore              =  85, // 0x55
    _sastore              =  86, // 0x56
    _pop                  =  87, // 0x57
    _pop2                 =  88, // 0x58
    _dup                  =  89, // 0x59
    _dup_x1               =  90, // 0x5a
    _dup_x2               =  91, // 0x5b
    _dup2                 =  92, // 0x5c
    _dup2_x1              =  93, // 0x5d
    _dup2_x2              =  94, // 0x5e
    _swap                 =  95, // 0x5f
    _iadd                 =  96, // 0x60
    _ladd                 =  97, // 0x61
    _fadd                 =  98, // 0x62
    _dadd                 =  99, // 0x63
    _isub                 = 100, // 0x64
    _lsub                 = 101, // 0x65
    _fsub                 = 102, // 0x66
    _dsub                 = 103, // 0x67
    _imul                 = 104, // 0x68
    _lmul                 = 105, // 0x69
    _fmul                 = 106, // 0x6a
    _dmul                 = 107, // 0x6b
    _idiv                 = 108, // 0x6c
    _ldiv                 = 109, // 0x6d
    _fdiv                 = 110, // 0x6e
    _ddiv                 = 111, // 0x6f
    _irem                 = 112, // 0x70
    _lrem                 = 113, // 0x71
    _frem                 = 114, // 0x72
    _drem                 = 115, // 0x73
    _ineg                 = 116, // 0x74
    _lneg                 = 117, // 0x75
    _fneg                 = 118, // 0x76
    _dneg                 = 119, // 0x77
    _ishl                 = 120, // 0x78
    _lshl                 = 121, // 0x79
    _ishr                 = 122, // 0x7a
    _lshr                 = 123, // 0x7b
    _iushr                = 124, // 0x7c
    _lushr                = 125, // 0x7d
    _iand                 = 126, // 0x7e
    _land                 = 127, // 0x7f
    _ior                  = 128, // 0x80
    _lor                  = 129, // 0x81
    _ixor                 = 130, // 0x82
    _lxor                 = 131, // 0x83
    _iinc                 = 132, // 0x84
    _i2l                  = 133, // 0x85
    _i2f                  = 134, // 0x86
    _i2d                  = 135, // 0x87
    _l2i                  = 136, // 0x88
    _l2f                  = 137, // 0x89
    _l2d                  = 138, // 0x8a
    _f2i                  = 139, // 0x8b
    _f2l                  = 140, // 0x8c
    _f2d                  = 141, // 0x8d
    _d2i                  = 142, // 0x8e
    _d2l                  = 143, // 0x8f
    _d2f                  = 144, // 0x90
    _i2b                  = 145, // 0x91
    _i2c                  = 146, // 0x92
    _i2s                  = 147, // 0x93
    _lcmp                 = 148, // 0x94
    _fcmpl                = 149, // 0x95
    _fcmpg                = 150, // 0x96
    _dcmpl                = 151, // 0x97
    _dcmpg                = 152, // 0x98
    _ifeq                 = 153, // 0x99
    _ifne                 = 154, // 0x9a
    _iflt                 = 155, // 0x9b
    _ifge                 = 156, // 0x9c
    _ifgt                 = 157, // 0x9d
    _ifle                 = 158, // 0x9e
    _if_icmpeq            = 159, // 0x9f
    _if_icmpne            = 160, // 0xa0
    _if_icmplt            = 161, // 0xa1
    _if_icmpge            = 162, // 0xa2
    _if_icmpgt            = 163, // 0xa3
    _if_icmple            = 164, // 0xa4
    _if_acmpeq            = 165, // 0xa5
    _if_acmpne            = 166, // 0xa6
    _goto                 = 167, // 0xa7
    _jsr                  = 168, // 0xa8
    _ret                  = 169, // 0xa9
    _tableswitch          = 170, // 0xaa
    _lookupswitch         = 171, // 0xab
    _ireturn              = 172, // 0xac
    _lreturn              = 173, // 0xad
    _freturn              = 174, // 0xae
    _dreturn              = 175, // 0xaf
    _areturn              = 176, // 0xb0
    _return               = 177, // 0xb1
    _getstatic            = 178, // 0xb2
    _putstatic            = 179, // 0xb3
    _getfield             = 180, // 0xb4
    _putfield             = 181, // 0xb5
    _invokevirtual        = 182, // 0xb6
    _invokespecial        = 183, // 0xb7
    _invokestatic         = 184, // 0xb8
    _invokeinterface      = 185, // 0xb9
    _invokedynamic        = 186, // 0xba     // if EnableInvokeDynamic
    _new                  = 187, // 0xbb
    _newarray             = 188, // 0xbc
    _anewarray            = 189, // 0xbd
    _arraylength          = 190, // 0xbe
    _athrow               = 191, // 0xbf
    _checkcast            = 192, // 0xc0
    _instanceof           = 193, // 0xc1
    _monitorenter         = 194, // 0xc2
    _monitorexit          = 195, // 0xc3
    _wide                 = 196, // 0xc4
    _multianewarray       = 197, // 0xc5
    _ifnull               = 198, // 0xc6
    _ifnonnull            = 199, // 0xc7
    _goto_w               = 200, // 0xc8
    _jsr_w                = 201, // 0xc9
    _breakpoint           = 202, // 0xca

    number_of_java_codes,

    // JVM bytecodes
    _fast_agetfield       = number_of_java_codes,
    _fast_bgetfield       ,
    _fast_cgetfield       ,
    _fast_dgetfield       ,
    _fast_fgetfield       ,
    _fast_igetfield       ,
    _fast_lgetfield       ,
    _fast_sgetfield       ,

    _fast_aputfield       ,
    _fast_bputfield       ,
    _fast_zputfield       ,
    _fast_cputfield       ,
    _fast_dputfield       ,
    _fast_fputfield       ,
    _fast_iputfield       ,
    _fast_lputfield       ,
    _fast_sputfield       ,

    _fast_aload_0         ,
    _fast_iaccess_0       ,
    _fast_aaccess_0       ,
    _fast_faccess_0       ,

    _fast_iload           ,
    _fast_iload2          ,
    _fast_icaload         ,

    _fast_invokevfinal    ,
    _fast_linearswitch    ,
    _fast_binaryswitch    ,

    // special handling of oop constants:
    _fast_aldc            ,
    _fast_aldc_w          ,

    _return_register_finalizer    ,

    _shouldnotreachhere,      // For debugging

    // Platform specific JVM bytecodes
#ifdef TARGET_ARCH_x86
# include "bytecodes_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytecodes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytecodes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytecodes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytecodes_ppc.hpp"
#endif


    number_of_codes
  };
将操作栈中的栈顶元素弹出并设值本地变量表对应的变量。 astore astore_<n> 指令_astore,_astore_0,_astore_1,_astore_2,_astore_3   dstore dstore_<n>   fstore fstore_<n>   istore istore_<n>   lstore lstore_<n>  
int i = 10;
long l = 100L;
float f = 0.1F;
double d = 0.1;
String s = "abc";
char c = 'a';
        0: bipush        10        2: istore_1        3: ldc2_w        #2                  // long 100l        6: lstore_2        7: ldc           #4                  // float 0.1f        9: fstore        4       11: ldc2_w        #5                  // double 0.1d       14: dstore        5       16: ldc           #7                  // String abc       18: astore        7       20: bipush        97       22: istore        8     aastore   bastore   castore   dastore   fastore   iastore   lastore   sastore   将本地变量表中对应的变量压入到操作栈中。 aload aload_<n>
指令_aload_0,_aload_1,_aload_2,_aload_3,_fast_aload_0
 
dload
dload_<n>
 
fload
fload_<n>
 
iload
iload_<n>
 
lload
lload_<n>
 
aaload
 
baload
 
caload
 
daload
 
faload
 
iaload
 
laload
 
saload
int i2 = i;
long l2 = l;
float f2 = f;
double d2 = d;
String s2 = s;
char c2 = c;
 
      24: iload_1
      25: istore        9
      27: lload_2
      28: lstore        10
      30: fload         4
      32: fstore        12
      34: dload         5
      36: dstore        13
      38: aload         7
      40: astore        15
      42: iload         8
      44: istore        16
指令_aload_0,_aload_1,_aload_2,_aload_3,_fast_aload_0   dload dload_<n>   fload fload_<n>   iload iload_<n>   lload lload_<n>   aaload   baload   caload   daload   faload   iaload   laload   saload
int i2 = i;
long l2 = l;
float f2 = f;
double d2 = d;
String s2 = s;
char c2 = c;
 
      24: iload_1
      25: istore        9
      27: lload_2
      28: lstore        10
      30: fload         4
      32: fstore        12
      34: dload         5
      36: dstore        13
      38: aload         7
      40: astore        15
      42: iload         8
      44: istore        16
      24: iload_1       25: istore        9       27: lload_2       28: lstore        10       30: fload         4       32: fstore        12       34: dload         5       36: dstore        13       38: aload         7       40: astore        15       42: iload         8       44: istore        16   创建对象new例子: new
public class JavaNew {

	public static void main(String[] args) {
		Object obj = new Object();
	}
}
反汇编结果:
>javap -c JavaNew
Compiled from "JavaNew.java"
public class JavaNew {
  public JavaNew();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return
 
  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/Object
       3: dup
       4: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       7: astore_1
       8: return
}
>javap -c JavaNew Compiled from "JavaNew.java" public class JavaNew {   public JavaNew();     Code:        0: aload_0        1: invokespecial #1                  // Method java/lang/Object."<init>": ()V        4: return     public static void main(java.lang.String[]);     Code:        0: new           #2                  // class java/lang/Object        3: dup        4: invokespecial #1                  // Method java/lang/Object."<init>": ()V        7: astore_1        8: return } 从反编译的结果看,生成了一个构造方法,源代码中我没有为JavaNew定义任何构造方法,如果没有显式定义构造方法,Java会隐式定义一个默认的无参构造方法。在public JavaNew();下面是这个构造方法的字节码实现指令,其中一条重要的指令:invokespecial #1,在JVM解释执行遇到这个指令的时候,JVM会调用一个特殊方法:<init>,这从后面的注释也可以看出来:// Method java/lang/Object."<init>":()V,它对应Java层面的构造方法:public JavaNew() {},在这里我们可以认为构造方法也是一个特殊的构造方法,特殊在于在Java层面上它的方法名在Java层面看和类型一样,但在JVM层面却对应的是:<init>,另外没有显式的返回类型,只有参数类型是一样的。最后要注意的事后面的()V,它是构造方法的签名,其形式如下: (参数类型签名列表)返回类型签名 在另一篇文章: https://lobin.iteye.com/blog/2437928,讲GetMethodID函数的时候也会传入对应方法的签名。 创建数组newarray例子: newarray
public class JavaNewArray {

	public static void main(String[] args) {
		int test[] = new int[123];
	}
}
 反汇编结果:
>javap -c JavaNewArray
Compiled from "JavaNewArray.java"
public class JavaNewArray {
  public JavaNewArray();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        123
       2: newarray       int
       4: astore_1
       5: return
}
 ldc指令 将运行时常量池中的item压入到操作栈。
String str = "string abc";
        0: ldc           #2                  // String string abc        2: astore_1  
String str = new String("string abc");
 
       0: new           #2                  // class java/lang/String
       3: dup
       4: ldc           #3                  // String string abc
       6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
       9: astore_1
       0: new           #2                  // class java/lang/String        3: dup        4: ldc           #3                  // String string abc        6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V        9: astore_1 在这个例子中,将字符串"string abc"压入到操作栈。   iconst_<i>指令 将int常量i压入操作栈。如iconst_m1 = 2 (0x2), iconst_0 = 3 (0x3), iconst_1 = 4 (0x4), iconst_2 = 5 (0x5), iconst_3 = 6 (0x6), iconst_4 = 7 (0x7), iconst_5 = 8 (0x8)分别表示将-1, 0, 1, 2, 3, 4, 5压入操作栈。        5: iconst_1   类加载时,在验证阶段针对指令的类型检查,参考 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.9,其中列举了所有在验证阶段会进行针对指令的类型检查。aaload、aastore、aconst_null、aload, aload_<n>、anewarray、areturn、arraylength、astore, astore_<n>、athrow等.   在以下例子中:
public class VariableSetTest {

    private int value;

    public static void main(String[] args) {
        VariableSetTest test = new VariableSetTest();


        test.value++;
        System.out.println(test.value);
    }
}
 public class VariableSetTest {   public VariableSetTest();     Code:        0: aload_0        1: invokespecial #1                  // Method java/lang/Object."<init>":()V        4: return     public static void main(java.lang.String[]);     Code:        0: new           #2                  // class VariableSetTest        3: dup        4: invokespecial #3                  // Method "<init>":()V        7: astore_1        8: aload_1        9: dup       10: getfield      #4                  // Field value:I       13: iconst_1       14: iadd       15: putfield      #4                  // Field value:I       18: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;       21: aload_1       22: getfield      #4                  // Field value:I       25: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V       28: return }
public class VariableSetTest2 {

    public static void main(String[] args) {
        int value = 0;
        value++;
        System.out.println(value);
    }
}
 public class VariableSetTest2 {   public VariableSetTest2();     Code:        0: aload_0        1: invokespecial #1                  // Method java/lang/Object."<init>":()V        4: return     public static void main(java.lang.String[]);     Code:        0: iconst_0        1: istore_1        2: iinc          1, 1        5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;        8: iload_1        9: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V       12: return } 1、VariableSetTest中的++操作对应的指令为14: iadd,但 VariableSetTest2中的++操作对应的指令为 2: iinc          1, 1。 2、 VariableSetTest, VariableSetTest2中的++操作会更新value的值,但在反编译后的指令码中没有astore类似的指令更新本地变量表中对应变量value的值。

猜你喜欢

转载自lobin.iteye.com/blog/2440503