Loading... # 引言 最近在看单例模式,为了更好的理解其中的过程,对JVM层面的过程进行了更深维度的分析,这些指令助记符是有必要了解的。当然,中文的这些来源于网络,摘自(https://mp.weixin.qq.com/s?src=11×tamp=1619712228&ver=3038&signature=E3YzYyeNeL7twZ77X6P7Jz8wg-u4B4ltN236bEtU2IcmEzm0DQ3oxu*9TnE4wALDP5wqmUN0*zeJWkjlt5BjRjux*hECCG76TyuK5P0UshOTg0a8fzXOYveYq*pO9CpN&new=1) # 中文解释 | 指令码 |助记符 |说明| | ---- | ---- | ---- | | 0x00 |nop |什么都不做| | 0x01 |aconst_null| 将null推送至栈顶| | 0x02 |iconst_m1 |将int型-1推送至栈顶| | 0x03 |iconst_0 |将int型0推送至栈顶| | 0x04 |iconst_1 |将int型1推送至栈顶| | 0x05 |iconst_2 |将int型2推送至栈顶| | 0x06 |iconst_3 |将int型3推送至栈顶| | 0x07 |iconst_4 |将int型4推送至栈顶| | 0x08 |iconst_5 |将int型5推送至栈顶| | 0x09 |lconst_0 |将long型0推送至栈顶| | 0x0a |lconst_1 |将long型1推送至栈顶| | 0x0b |fconst_0 |将float型0推送至栈顶| | 0x0c |fconst_1 |将float型1推送至栈顶| | 0x0d |fconst_2 |将float型2推送至栈顶| | 0x0e |dconst_0 |将double型0推送至栈顶| | 0x0f |dconst_1 |将double型1推送至栈顶| | 0x10 |bipush |将单字节的常量值(-128~127)推送至栈顶| | 0x11 |sipush |将一个短整型常量值(-32768~32767)推送至栈顶| | 0x12 |ldc |将int, float或String型常量值从常量池中推送至栈顶| | 0x13 |ldc_w |将int, float或String型常量值从常量池中推送至栈顶(宽索引)| | 0x14 |ldc2_w |将long或double型常量值从常量池中推送至栈顶(宽索引)| | 0x15 |iload |将指定的int型本地变量推送至栈顶| | 0x16 |lload |将指定的long型本地变量推送至栈顶| | 0x17 |fload |将指定的float型本地变量推送至栈顶| | 0x18 |dload |将指定的double型本地变量推送至栈顶| | 0x19 |aload |将指定的引用类型本地变量推送至栈顶| | 0x1a |iload_0 |将第0个int型本地变量推送至栈顶| | 0x1b |iload_1 |将第1个int型本地变量推送至栈顶| | 0x1c |iload_2 |将第2个int型本地变量推送至栈顶| | 0x1d |iload_3 |将第3个int型本地变量推送至栈顶| | 0x1e |lload_0 |将第0个long型本地变量推送至栈顶| | 0x1f |lload_1 |将第1个long型本地变量推送至栈顶| | 0x20 |lload_2 |将第2个long型本地变量推送至栈顶| | 0x21 |lload_3 |将第3个long型本地变量推送至栈顶| | 0x22 |fload_0 |将第0个float型本地变量推送至栈顶| | 0x23 |fload_1 |将第1个float型本地变量推送至栈顶| | 0x24 |fload_2 |将第2个float型本地变量推送至栈顶| | 0x25 |fload_3 |将第3个float型本地变量推送至栈顶| | 0x26 |dload_0 |将第0个double型本地变量推送至栈顶| | 0x27 |dload_1 |将第1个double型本地变量推送至栈顶| | 0x28 |dload_2 |将第2个double型本地变量推送至栈顶| | 0x29 |dload_3 |将第3个double型本地变量推送至栈顶| | 0x2a |aload_0 |将第0个引用类型本地变量推送至栈顶| | 0x2b |aload_1 |将第1个引用类型本地变量推送至栈顶| | 0x2c |aload_2 |将第2个引用类型本地变量推送至栈顶| | 0x2d |aload_3 |将第3个引用类型本地变量推送至栈顶| | 0x2e |iaload| 将int型数组指定索引的值推送至栈顶| | 0x2f |laload| 将long型数组指定索引的值推送至栈顶| | 0x30 |faload| 将float型数组指定索引的值推送至栈顶| | 0x31 |daload| 将double型数组指定索引的值推送至栈顶| | 0x32 |aaload| 将引用型数组指定索引的值推送至栈顶| | 0x33 |baload| 将boolean或byte型数组指定索引的值推送至栈顶| | 0x34 |caload| 将char型数组指定索引的值推送至栈顶| | 0x35 |saload| 将short型数组指定索引的值推送至栈顶| | 0x36 |istore| 将栈顶int型数值存入指定本地变量| | 0x37 |lstore| 将栈顶long型数值存入指定本地变量| | 0x38 |fstore| 将栈顶float型数值存入指定本地变量| | 0x39 |dstore| 将栈顶double型数值存入指定本地变量| | 0x3a |astore| 将栈顶引用型数值存入指定本地变量| | 0x3b |istore_0|将栈顶int型数值存入第0个本地变量| | 0x3c |istore_1|将栈顶int型数值存入第1个本地变量| | 0x3d |istore_2|将栈顶int型数值存入第2个本地变量| | 0x3e |istore_3|将栈顶int型数值存入第3个本地变量| | 0x3f |lstore_0|将栈顶long型数值存入第0个本地变量| | 0x40 |lstore_1|将栈顶long型数值存入第1个本地变量| | 0x41 |lstore_2|将栈顶long型数值存入第2个本地变量| | 0x42 |lstore_3|将栈顶long型数值存入第3个本地变量| | 0x43 |fstore_0|将栈顶float型数值存入第0个本地变量| | 0x44 |fstore_1|将栈顶float型数值存入第1个本地变量| | 0x45 |fstore_2|将栈顶float型数值存入第2个本地变量| | 0x46 |fstore_3|将栈顶float型数值存入第3个本地变量| | 0x47 |dstore_0|将栈顶double型数值存入第0个本地变量| | 0x48 |dstore_1|将栈顶double型数值存入第1个本地变量| | 0x49 |dstore_2|将栈顶double型数值存入第2个本地变量| | 0x4a |dstore_3|将栈顶double型数值存入第3个本地变量| | 0x4b |astore_0|将栈顶引用型数值存入第0个本地变量| | 0x4c |astore_1|将栈顶引用型数值存入第1个本地变量| | 0x4d |astore_2|将栈顶引用型数值存入第2个本地变量| | 0x4e |astore_3|将栈顶引用型数值存入第3个本地变量| | 0x4f |iastore|将栈顶int型数值存入指定数组的指定索引位置| | 0x50 |lastore|将栈顶long型数值存入指定数组的指定索引位置| | 0x51 |fastore|将栈顶float型数值存入指定数组的指定索引位置| | 0x52 |dastore|将栈顶double型数值存入指定数组的指定索引位置| | 0x53 |aastore|将栈顶引用型数值存入指定数组的指定索引位置| | 0x54 |bastore|将栈顶boolean或byte型数值存入指定数组的指定索引位置| | 0x55 |castore|将栈顶char型数值存入指定数组的指定索引位置| | 0x56 |sastore|将栈顶short型数值存入指定数组的指定索引位置| | 0x57 |pop |将栈顶数值弹出 (数值不能是long或double类型的)| | 0x58 |pop2 |将栈顶的一个(long或double类型的)或两个数值弹出(其它)| | 0x59 |dup |复制栈顶数值并将复制值压入栈顶| | 0x5a |dup_x1 |复制栈顶数值并将两个复制值压入栈顶| | 0x5b |dup_x2 |复制栈顶数值并将三个(或两个)复制值压入栈顶| | 0x5c |dup2 |复制栈顶一个(long或double类型的)或两个(其它)数值并将复制值压入栈顶| | 0x5d |dup2_x1| |<待补充>| | 0x5e |dup2_x2 |<待补充>| | 0x5f |swap |将栈最顶端的两个数值互换(数值不能是long或double类型的)| | 0x60 |iadd |将栈顶两int型数值相加并将结果压入栈顶| | 0x61 |ladd |将栈顶两long型数值相加并将结果压入栈顶| | 0x62 |fadd |将栈顶两float型数值相加并将结果压入栈顶| | 0x63 |dadd |将栈顶两double型数值相加并将结果压入栈顶| | 0x64 |isub |将栈顶两int型数值相减并将结果压入栈顶| | 0x65 |lsub |将栈顶两long型数值相减并将结果压入栈顶| | 0x66 |fsub |将栈顶两float型数值相减并将结果压入栈顶| | 0x67 |dsub |将栈顶两double型数值相减并将结果压入栈顶| | 0x68 |imul |将栈顶两int型数值相乘并将结果压入栈顶| | 0x69 |lmul |将栈顶两long型数值相乘并将结果压入栈顶| | 0x6a |fmul |将栈顶两float型数值相乘并将结果压入栈顶| | 0x6b |dmul |将栈顶两double型数值相乘并将结果压入栈顶| | 0x6c |idiv |将栈顶两int型数值相除并将结果压入栈顶| | 0x6d |ldiv |将栈顶两long型数值相除并将结果压入栈顶| | 0x6e |fdiv |将栈顶两float型数值相除并将结果压入栈顶| | 0x6f |ddiv |将栈顶两double型数值相除并将结果压入栈顶| | 0x70 |irem |将栈顶两int型数值作取模运算并将结果压入栈顶| | 0x71 |lrem |将栈顶两long型数值作取模运算并将结果压入栈顶| | 0x72 |frem |将栈顶两float型数值作取模运算并将结果压入栈顶| | 0x73 |drem |将栈顶两double型数值作取模运算并将结果压入栈顶| | 0x74 |ineg |将栈顶int型数值取负并将结果压入栈顶| | 0x75 |lneg |将栈顶long型数值取负并将结果压入栈顶| | 0x76 |fneg |将栈顶float型数值取负并将结果压入栈顶| | 0x77 |dneg |将栈顶double型数值取负并将结果压入栈顶| | 0x78 |ishl |将int型数值左移位指定位数并将结果压入栈顶| | 0x79 |lshl |将long型数值左移位指定位数并将结果压入栈顶| | 0x7a |ishr |将int型数值右(符号)移位指定位数并将结果压入栈顶| | 0x7b |lshr |将long型数值右(符号)移位指定位数并将结果压入栈顶| | 0x7c |iushr |将int型数值右(无符号)移位指定位数并将结果压入栈顶| | 0x7d |lushr |将long型数值右(无符号)移位指定位数并将结果压入栈顶| | 0x7e |iand |将栈顶两int型数值作“按位与”并将结果压入栈顶| | 0x7f |land |将栈顶两long型数值作“按位与”并将结果压入栈顶| | 0x80 |ior |将栈顶两int型数值作“按位或”并将结果压入栈顶| | 0x81 |lor |将栈顶两long型数值作“按位或”并将结果压入栈顶| | 0x82 |ixor |将栈顶两int型数值作“按位异或”并将结果压入栈顶| | 0x83 |lxor |将栈顶两long型数值作“按位异或”并将结果压入栈顶| | 0x84 |iinc |将指定int型变量增加指定值,可以有两个变量,分别表示index, const,index指第index个int型本地变量,const增加的值| | 0x85 |i2l |将栈顶int型数值强制转换成long型数值并将结果压入栈顶| | 0x86 |i2f |将栈顶int型数值强制转换成float型数值并将结果压入栈顶| | 0x87 |i2d |将栈顶int型数值强制转换成double型数值并将结果压入栈顶| | 0x88 |l2i |将栈顶long型数值强制转换成int型数值并将结果压入栈顶| | 0x89 |l2f |将栈顶long型数值强制转换成float型数值并将结果压入栈顶| | 0x8a |l2d |将栈顶long型数值强制转换成double型数值并将结果压入栈顶| | 0x8b |f2i |将栈顶float型数值强制转换成int型数值并将结果压入栈顶| | 0x8c |f2l |将栈顶float型数值强制转换成long型数值并将结果压入栈顶| | 0x8d |f2d |将栈顶float型数值强制转换成double型数值并将结果压入栈顶| | 0x8e |d2i |将栈顶double型数值强制转换成int型数值并将结果压入栈顶| | 0x8f |d2l |将栈顶double型数值强制转换成long型数值并将结果压入栈顶| | 0x90 |d2f |将栈顶double型数值强制转换成float型数值并将结果压入栈顶| | 0x91 |i2b |将栈顶int型数值强制转换成byte型数值并将结果压入栈顶| | 0x92 |i2c |将栈顶int型数值强制转换成char型数值并将结果压入栈顶| | 0x93 |i2s |将栈顶int型数值强制转换成short型数值并将结果压入栈顶| | 0x94 |lcmp |比较栈顶两long型数值大小,并将结果(1,0,-1)压入栈顶| | 0x95 |fcmpl |比较栈顶两float型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将-1压入栈顶| | 0x96 |fcmpg |比较栈顶两float型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将1压入栈顶| | 0x97 |dcmpl |比较栈顶两double型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将-1压入栈顶| | 0x98 |dcmpg |比较栈顶两double型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将1压入栈顶| | 0x99 |ifeq |当栈顶int型数值等于0时跳转| | 0x9a |ifne |当栈顶int型数值不等于0时跳转| | 0x9b |iflt |当栈顶int型数值小于0时跳转| | 0x9c |ifge |当栈顶int型数值大于等于0时跳转| | 0x9d |ifgt |当栈顶int型数值大于0时跳转| | 0x9e |ifle |当栈顶int型数值小于等于0时跳转| | 0x9f |if_icmpeq |比较栈顶两int型数值大小,当结果等于0时跳转| | 0xa0 |if_icmpne |比较栈顶两int型数值大小,当结果不等于0时跳转| | 0xa1 |if_icmplt |比较栈顶两int型数值大小,当结果小于0时跳转| | 0xa2 |if_icmpge |比较栈顶两int型数值大小,当结果大于等于0时跳转| | 0xa3 |if_icmpgt |比较栈顶两int型数值大小,当结果大于0时跳转| | 0xa4 |if_icmple |比较栈顶两int型数值大小,当结果小于等于0时跳转| | 0xa5 |if_acmpeq |比较栈顶两引用型数值,当结果相等时跳转| | 0xa6 |if_acmpne |比较栈顶两引用型数值,当结果不相等时跳转| | 0xa7 |goto |无条件跳转| | 0xa8 |jsr |跳转至指定16位offset位置,并将jsr下一条指令地址压入栈顶| | 0xa9 |ret |返回至本地变量指定的index的指令位置(一般与jsr, jsr_w联合使用)| | 0xaa |tableswitch|用于switch条件跳转,case值连续(可变长度指令)| | 0xab |lookupswitch|用于switch条件跳转,case值不连续(可变长度指令)| | 0xac |ireturn |从当前方法返回int| | 0xad |lreturn |从当前方法返回long| | 0xae |freturn |从当前方法返回float| | 0xaf |dreturn |从当前方法返回double| | 0xb0 |areturn |从当前方法返回对象引用| | 0xb1 |return| |从当前方法返回void| | 0xb2 |getstatic |获取指定类的静态域,并将其值压入栈顶| | 0xb3 |putstatic |为指定的类的静态域赋值| | 0xb4 |getfield |获取指定类的实例域,并将其值压入栈顶| | 0xb5 |putfield |为指定的类的实例域赋值| | 0xb6 |invokevirtual |调用实例方法| | 0xb7 |invokespecial |调用超类构造方法,实例初始化方法,私有方法| | 0xb8 |invokestatic |调用静态方法| | 0xb9 |invokeinterface| 调用接口方法| | 0xba |–| - | | 0xbb |new |创建一个对象,并将其引用值压入栈顶| | 0xbc |newarray |创建一个指定原始类型(如int, float, char…)的数组,并将其引用值压入栈顶| | 0xbd |anewarray |创建一个引用型(如类,接口,数组)的数组,并将其引用值压入栈顶| | 0xbe |arraylength| 获得数组的长度值并压入栈顶| | 0xbf |athrow| 将栈顶的异常抛出| | 0xc0 |checkcast |检验类型转换,检验未通过将抛出ClassCastException| | 0xc1 |instanceof |检验对象是否是指定的类的实例,如果是将1压入栈顶,否则将0压入栈顶| | 0xc2 |monitorenter |获得对象的锁,用于同步方法或同步块| | 0xc3 |monitorexit |释放对象的锁,用于同步方法或同步块| | 0xc4 |wide |当本地变量的索引超过255时使用该指令扩展索引宽度。| | 0xc5 |multianewarray| create a new array of dimensions dimensions with elements of type identified by class reference in constant pool index (indexbyte1 << 8 + indexbyte2); the sizes of each dimension is identified by count1, [count2, etc.]| | 0xc6 |ifnull |if value is null, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)| | 0xc7 |ifnonnull |if value is not null, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)| | 0xc8 |goto_w |goes to another instruction at branchoffset (signed int constructed from unsigned bytes branchbyte1 << 24 + branchbyte2 << 16 + branchbyte3 << 8 + branchbyte4)| | 0xc9 |jsr_w |jump to subroutine at branchoffset (signed int constructed from unsigned bytes branchbyte1 << 24 + branchbyte2 << 16 + branchbyte3 << 8 + branchbyte4) and place the return address on the stack| | 0xca |breakpoint| reserved for breakpoints in Java debuggers; should not appear in any class file| | 0xcb-0xfd| 未命名 |these values are currently unassigned for opcodes and are reserved for future use| | 0xfe |impdep1 |reserved for implementation-dependent operations within debuggers; should not appear in any class file| | 0xff |impdep2| reserved for implementation-dependent operations within debuggers; should not appear in any class file| # 选自维基百科中的片段 地址:https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings | Mnemonic | Opcode (in hex) | Opcode (in binary) | Other bytes [count]: [operand labels] | Stack [before]→[after] | Description | | :----------------------------------------------------------: | :-------------: | :----------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | | aaload | 32 | 0011 0010 | | arrayref, index → value | load onto the stack a reference from an array | | aastore | 53 | 0101 0011 | | arrayref, index, value → | store a reference in an array | | aconst_null | 01 | 0000 0001 | | → null | push a *null* reference onto the stack | | aload | 19 | 0001 1001 | 1: index | → objectref | load a reference onto the stack from a local variable *#index* | | aload_0 | 2a | 0010 1010 | | → objectref | load a reference onto the stack from local variable 0 | | aload_1 | 2b | 0010 1011 | | → objectref | load a reference onto the stack from local variable 1 | | aload_2 | 2c | 0010 1100 | | → objectref | load a reference onto the stack from local variable 2 | | aload_3 | 2d | 0010 1101 | | → objectref | load a reference onto the stack from local variable 3 | | anewarray | bd | 1011 1101 | 2: indexbyte1, indexbyte2 | count → arrayref | create a new array of references of length *count* and component type identified by the class reference *index* (indexbyte1 << 8 \| indexbyte2) in the constant pool | | areturn | b0 | 1011 0000 | | objectref → [empty] | return a reference from a method | | arraylength | be | 1011 1110 | | arrayref → length | get the length of an array | | astore | 3a | 0011 1010 | 1: index | objectref → | store a reference into a local variable *#index* | | astore_0 | 4b | 0100 1011 | | objectref → | store a reference into local variable 0 | | astore_1 | 4c | 0100 1100 | | objectref → | store a reference into local variable 1 | | astore_2 | 4d | 0100 1101 | | objectref → | store a reference into local variable 2 | | astore_3 | 4e | 0100 1110 | | objectref → | store a reference into local variable 3 | | athrow | bf | 1011 1111 | | objectref → [empty], objectref | throws an error or exception (notice that the rest of the stack is cleared, leaving only a reference to the Throwable) | | baload | 33 | 0011 0011 | | arrayref, index → value | load a byte or Boolean value from an array | | bastore | 54 | 0101 0100 | | arrayref, index, value → | store a byte or Boolean value into an array | | bipush | 10 | 0001 0000 | 1: byte | → value | push a *byte* onto the stack as an integer *value* | | breakpoint | ca | 1100 1010 | | | reserved for breakpoints in Java debuggers; should not appear in any class file | | caload | 34 | 0011 0100 | | arrayref, index → value | load a char from an array | | castore | 55 | 0101 0101 | | arrayref, index, value → | store a char into an array | | checkcast | c0 | 1100 0000 | 2: indexbyte1, indexbyte2 | objectref → objectref | checks whether an *objectref* is of a certain type, the class reference of which is in the constant pool at *index* (indexbyte1 << 8 \| indexbyte2) | | d2f | 90 | 1001 0000 | | value → result | convert a double to a float | | d2i | 8e | 1000 1110 | | value → result | convert a double to an int | | d2l | 8f | 1000 1111 | | value → result | convert a double to a long | | dadd | 63 | 0110 0011 | | value1, value2 → result | add two doubles | | daload | 31 | 0011 0001 | | arrayref, index → value | load a double from an array | | dastore | 52 | 0101 0010 | | arrayref, index, value → | store a double into an array | | dcmpg | 98 | 1001 1000 | | value1, value2 → result | compare two doubles, 1 on NaN | | dcmpl | 97 | 1001 0111 | | value1, value2 → result | compare two doubles, -1 on NaN | | dconst_0 | 0e | 0000 1110 | | → 0.0 | push the constant *0.0* (a *double*) onto the stack | | dconst_1 | 0f | 0000 1111 | | → 1.0 | push the constant *1.0* (a *double*) onto the stack | | ddiv | 6f | 0110 1111 | | value1, value2 → result | divide two doubles | | dload | 18 | 0001 1000 | 1: index | → value | load a double *value* from a local variable *#index* | | dload_0 | 26 | 0010 0110 | | → value | load a double from local variable 0 | | dload_1 | 27 | 0010 0111 | | → value | load a double from local variable 1 | | dload_2 | 28 | 0010 1000 | | → value | load a double from local variable 2 | | dload_3 | 29 | 0010 1001 | | → value | load a double from local variable 3 | | dmul | 6b | 0110 1011 | | value1, value2 → result | multiply two doubles | | dneg | 77 | 0111 0111 | | value → result | negate a double | | drem | 73 | 0111 0011 | | value1, value2 → result | get the remainder from a division between two doubles | | dreturn | af | 1010 1111 | | value → [empty] | return a double from a method | | dstore | 39 | 0011 1001 | 1: index | value → | store a double *value* into a local variable *#index* | | dstore_0 | 47 | 0100 0111 | | value → | store a double into local variable 0 | | dstore_1 | 48 | 0100 1000 | | value → | store a double into local variable 1 | | dstore_2 | 49 | 0100 1001 | | value → | store a double into local variable 2 | | dstore_3 | 4a | 0100 1010 | | value → | store a double into local variable 3 | | dsub | 67 | 0110 0111 | | value1, value2 → result | subtract a double from another | | dup | 59 | 0101 1001 | | value → value, value | duplicate the value on top of the stack | | dup_x1 | 5a | 0101 1010 | | value2, value1 → value1, value2, value1 | insert a copy of the top value into the stack two values from the top. value1 and value2 must not be of the type double or long. | | dup_x2 | 5b | 0101 1011 | | value3, value2, value1 → value1, value3, value2, value1 | insert a copy of the top value into the stack two (if value2 is double or long it takes up the entry of value3, too) or three values (if value2 is neither double nor long) from the top | | dup2 | 5c | 0101 1100 | | {value2, value1} → {value2, value1}, {value2, value1} | duplicate top two stack words (two values, if value1 is not double nor long; a single value, if value1 is double or long) | | dup2_x1 | 5d | 0101 1101 | | value3, {value2, value1} → {value2, value1}, value3, {value2, value1} | duplicate two words and insert beneath third word (see explanation above) | | dup2_x2 | 5e | 0101 1110 | | {value4, value3}, {value2, value1} → {value2, value1}, {value4, value3}, {value2, value1} | duplicate two words and insert beneath fourth word | | f2d | 8d | 1000 1101 | | value → result | convert a float to a double | | f2i | 8b | 1000 1011 | | value → result | convert a float to an int | | f2l | 8c | 1000 1100 | | value → result | convert a float to a long | | fadd | 62 | 0110 0010 | | value1, value2 → result | add two floats | | faload | 30 | 0011 0000 | | arrayref, index → value | load a float from an array | | fastore | 51 | 0101 0001 | | arrayref, index, value → | store a float in an array | | fcmpg | 96 | 1001 0110 | | value1, value2 → result | compare two floats, 1 on NaN | | fcmpl | 95 | 1001 0101 | | value1, value2 → result | compare two floats, -1 on NaN | | fconst_0 | 0b | 0000 1011 | | → 0.0f | push *0.0f* on the stack | | fconst_1 | 0c | 0000 1100 | | → 1.0f | push *1.0f* on the stack | | fconst_2 | 0d | 0000 1101 | | → 2.0f | push *2.0f* on the stack | | fdiv | 6e | 0110 1110 | | value1, value2 → result | divide two floats | | fload | 17 | 0001 0111 | 1: index | → value | load a float *value* from a local variable *#index* | | fload_0 | 22 | 0010 0010 | | → value | load a float *value* from local variable 0 | | fload_1 | 23 | 0010 0011 | | → value | load a float *value* from local variable 1 | | fload_2 | 24 | 0010 0100 | | → value | load a float *value* from local variable 2 | | fload_3 | 25 | 0010 0101 | | → value | load a float *value* from local variable 3 | | fmul | 6a | 0110 1010 | | value1, value2 → result | multiply two floats | | fneg | 76 | 0111 0110 | | value → result | negate a float | | frem | 72 | 0111 0010 | | value1, value2 → result | get the remainder from a division between two floats | | freturn | ae | 1010 1110 | | value → [empty] | return a float | | fstore | 38 | 0011 1000 | 1: index | value → | store a float *value* into a local variable *#index* | | fstore_0 | 43 | 0100 0011 | | value → | store a float *value* into local variable 0 | | fstore_1 | 44 | 0100 0100 | | value → | store a float *value* into local variable 1 | | fstore_2 | 45 | 0100 0101 | | value → | store a float *value* into local variable 2 | | fstore_3 | 46 | 0100 0110 | | value → | store a float *value* into local variable 3 | | fsub | 66 | 0110 0110 | | value1, value2 → result | subtract two floats | | getfield | b4 | 1011 0100 | 2: indexbyte1, indexbyte2 | objectref → value | get a field *value* of an object *objectref*, where the field is identified by field reference in the constant pool *index* (indexbyte1 << 8 \| indexbyte2) | | getstatic | b2 | 1011 0010 | 2: indexbyte1, indexbyte2 | → value | get a static field *value* of a class, where the field is identified by field reference in the constant pool *index* (indexbyte1 << 8 \| indexbyte2) | | goto | a7 | 1010 0111 | 2: branchbyte1, branchbyte2 | [no change] | goes to another instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | goto_w | c8 | 1100 1000 | 4: branchbyte1, branchbyte2, branchbyte3, branchbyte4 | [no change] | goes to another instruction at *branchoffset* (signed int constructed from unsigned bytes branchbyte1 << 24 \| branchbyte2 << 16 \| branchbyte3 << 8 \| branchbyte4) | | i2b | 91 | 1001 0001 | | value → result | convert an int into a byte | | i2c | 92 | 1001 0010 | | value → result | convert an int into a character | | i2d | 87 | 1000 0111 | | value → result | convert an int into a double | | i2f | 86 | 1000 0110 | | value → result | convert an int into a float | | i2l | 85 | 1000 0101 | | value → result | convert an int into a long | | i2s | 93 | 1001 0011 | | value → result | convert an int into a short | | iadd | 60 | 0110 0000 | | value1, value2 → result | add two ints | | iaload | 2e | 0010 1110 | | arrayref, index → value | load an int from an array | | iand | 7e | 0111 1110 | | value1, value2 → result | perform a bitwise AND on two integers | | iastore | 4f | 0100 1111 | | arrayref, index, value → | store an int into an array | | iconst_m1 | 02 | 0000 0010 | | → -1 | load the int value −1 onto the stack | | iconst_0 | 03 | 0000 0011 | | → 0 | load the int value 0 onto the stack | | iconst_1 | 04 | 0000 0100 | | → 1 | load the int value 1 onto the stack | | iconst_2 | 05 | 0000 0101 | | → 2 | load the int value 2 onto the stack | | iconst_3 | 06 | 0000 0110 | | → 3 | load the int value 3 onto the stack | | iconst_4 | 07 | 0000 0111 | | → 4 | load the int value 4 onto the stack | | iconst_5 | 08 | 0000 1000 | | → 5 | load the int value 5 onto the stack | | idiv | 6c | 0110 1100 | | value1, value2 → result | divide two integers | | if_acmpeq | a5 | 1010 0101 | 2: branchbyte1, branchbyte2 | value1, value2 → | if references are equal, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_acmpne | a6 | 1010 0110 | 2: branchbyte1, branchbyte2 | value1, value2 → | if references are not equal, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_icmpeq | 9f | 1001 1111 | 2: branchbyte1, branchbyte2 | value1, value2 → | if ints are equal, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_icmpge | a2 | 1010 0010 | 2: branchbyte1, branchbyte2 | value1, value2 → | if *value1* is greater than or equal to *value2*, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_icmpgt | a3 | 1010 0011 | 2: branchbyte1, branchbyte2 | value1, value2 → | if *value1* is greater than *value2*, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_icmple | a4 | 1010 0100 | 2: branchbyte1, branchbyte2 | value1, value2 → | if *value1* is less than or equal to *value2*, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_icmplt | a1 | 1010 0001 | 2: branchbyte1, branchbyte2 | value1, value2 → | if *value1* is less than *value2*, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | if_icmpne | a0 | 1010 0000 | 2: branchbyte1, branchbyte2 | value1, value2 → | if ints are not equal, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifeq | 99 | 1001 1001 | 2: branchbyte1, branchbyte2 | value → | if *value* is 0, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifge | 9c | 1001 1100 | 2: branchbyte1, branchbyte2 | value → | if *value* is greater than or equal to 0, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifgt | 9d | 1001 1101 | 2: branchbyte1, branchbyte2 | value → | if *value* is greater than 0, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifle | 9e | 1001 1110 | 2: branchbyte1, branchbyte2 | value → | if *value* is less than or equal to 0, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | iflt | 9b | 1001 1011 | 2: branchbyte1, branchbyte2 | value → | if *value* is less than 0, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifne | 9a | 1001 1010 | 2: branchbyte1, branchbyte2 | value → | if *value* is not 0, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifnonnull | c7 | 1100 0111 | 2: branchbyte1, branchbyte2 | value → | if *value* is not null, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | ifnull | c6 | 1100 0110 | 2: branchbyte1, branchbyte2 | value → | if *value* is null, branch to instruction at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) | | iinc | 84 | 1000 0100 | 2: index, const | [No change] | increment local variable *#index* by signed byte *const* | | iload | 15 | 0001 0101 | 1: index | → value | load an int *value* from a local variable *#index* | | iload_0 | 1a | 0001 1010 | | → value | load an int *value* from local variable 0 | | iload_1 | 1b | 0001 1011 | | → value | load an int *value* from local variable 1 | | iload_2 | 1c | 0001 1100 | | → value | load an int *value* from local variable 2 | | iload_3 | 1d | 0001 1101 | | → value | load an int *value* from local variable 3 | | impdep1 | fe | 1111 1110 | | | reserved for implementation-dependent operations within debuggers; should not appear in any class file | | impdep2 | ff | 1111 1111 | | | reserved for implementation-dependent operations within debuggers; should not appear in any class file | | imul | 68 | 0110 1000 | | value1, value2 → result | multiply two integers | | ineg | 74 | 0111 0100 | | value → result | negate int | | instanceof | c1 | 1100 0001 | 2: indexbyte1, indexbyte2 | objectref → result | determines if an object *objectref* is of a given type, identified by class reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | invokedynamic | ba | 1011 1010 | 4: indexbyte1, indexbyte2, 0, 0 | [arg1, arg2, ...] → result | invokes a dynamic method and puts the result on the stack (might be void); the method is identified by method reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | invokeinterface | b9 | 1011 1001 | 4: indexbyte1, indexbyte2, count, 0 | objectref, [arg1, arg2, ...] → result | invokes an interface method on object *objectref* and puts the result on the stack (might be void); the interface method is identified by method reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | invokespecial | b7 | 1011 0111 | 2: indexbyte1, indexbyte2 | objectref, [arg1, arg2, ...] → result | invoke instance method on object *objectref* and puts the result on the stack (might be void); the method is identified by method reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | invokestatic | b8 | 1011 1000 | 2: indexbyte1, indexbyte2 | [arg1, arg2, ...] → result | invoke a static method and puts the result on the stack (might be void); the method is identified by method reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | invokevirtual | b6 | 1011 0110 | 2: indexbyte1, indexbyte2 | objectref, [arg1, arg2, ...] → result | invoke virtual method on object *objectref* and puts the result on the stack (might be void); the method is identified by method reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | ior | 80 | 1000 0000 | | value1, value2 → result | bitwise int OR | | irem | 70 | 0111 0000 | | value1, value2 → result | logical int remainder | | ireturn | ac | 1010 1100 | | value → [empty] | return an integer from a method | | ishl | 78 | 0111 1000 | | value1, value2 → result | int shift left | | ishr | 7a | 0111 1010 | | value1, value2 → result | int arithmetic shift right | | istore | 36 | 0011 0110 | 1: index | value → | store int *value* into variable *#index* | | istore_0 | 3b | 0011 1011 | | value → | store int *value* into variable 0 | | istore_1 | 3c | 0011 1100 | | value → | store int *value* into variable 1 | | istore_2 | 3d | 0011 1101 | | value → | store int *value* into variable 2 | | istore_3 | 3e | 0011 1110 | | value → | store int *value* into variable 3 | | isub | 64 | 0110 0100 | | value1, value2 → result | int subtract | | iushr | 7c | 0111 1100 | | value1, value2 → result | int logical shift right | | ixor | 82 | 1000 0010 | | value1, value2 → result | int xor | | jsr | a8 | 1010 1000 | 2: branchbyte1, branchbyte2 | → address | jump to subroutine at *branchoffset* (signed short constructed from unsigned bytes branchbyte1 << 8 \| branchbyte2) and place the return address on the stack | | jsr_w | c9 | 1100 1001 | 4: branchbyte1, branchbyte2, branchbyte3, branchbyte4 | → address | jump to subroutine at *branchoffset* (signed int constructed from unsigned bytes branchbyte1 << 24 \| branchbyte2 << 16 \| branchbyte3 << 8 \| branchbyte4) and place the return address on the stack | | l2d | 8a | 1000 1010 | | value → result | convert a long to a double | | l2f | 89 | 1000 1001 | | value → result | convert a long to a float | | l2i | 88 | 1000 1000 | | value → result | convert a long to a int | | ladd | 61 | 0110 0001 | | value1, value2 → result | add two longs | | laload | 2f | 0010 1111 | | arrayref, index → value | load a long from an array | | land | 7f | 0111 1111 | | value1, value2 → result | bitwise AND of two longs | | lastore | 50 | 0101 0000 | | arrayref, index, value → | store a long to an array | | lcmp | 94 | 1001 0100 | | value1, value2 → result | push 0 if the two longs are the same, 1 if value1 is greater than value2, -1 otherwise | | lconst_0 | 09 | 0000 1001 | | → 0L | push *0L* (the number zero with type *long*) onto the stack | | lconst_1 | 0a | 0000 1010 | | → 1L | push *1L* (the number one with type *long*) onto the stack | | ldc | 12 | 0001 0010 | 1: index | → value | push a constant *#index* from a constant pool (String, int, float, Class, java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, or a dynamically-computed constant) onto the stack | | ldc_w | 13 | 0001 0011 | 2: indexbyte1, indexbyte2 | → value | push a constant *#index* from a constant pool (String, int, float, Class, java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, or a dynamically-computed constant) onto the stack (wide *index* is constructed as indexbyte1 << 8 \| indexbyte2) | | ldc2_w | 14 | 0001 0100 | 2: indexbyte1, indexbyte2 | → value | push a constant *#index* from a constant pool (double, long, or a dynamically-computed constant) onto the stack (wide *index* is constructed as indexbyte1 << 8 \| indexbyte2) | | ldiv | 6d | 0110 1101 | | value1, value2 → result | divide two longs | | lload | 16 | 0001 0110 | 1: index | → value | load a long value from a local variable *#index* | | lload_0 | 1e | 0001 1110 | | → value | load a long value from a local variable 0 | | lload_1 | 1f | 0001 1111 | | → value | load a long value from a local variable 1 | | lload_2 | 20 | 0010 0000 | | → value | load a long value from a local variable 2 | | lload_3 | 21 | 0010 0001 | | → value | load a long value from a local variable 3 | | lmul | 69 | 0110 1001 | | value1, value2 → result | multiply two longs | | lneg | 75 | 0111 0101 | | value → result | negate a long | | lookupswitch | ab | 1010 1011 | 8+: <0–3 bytes padding>, defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, npairs1, npairs2, npairs3, npairs4, match-offset pairs... | key → | a target address is looked up from a table using a key and execution continues from the instruction at that address | | lor | 81 | 1000 0001 | | value1, value2 → result | bitwise OR of two longs | | lrem | 71 | 0111 0001 | | value1, value2 → result | remainder of division of two longs | | lreturn | ad | 1010 1101 | | value → [empty] | return a long value | | lshl | 79 | 0111 1001 | | value1, value2 → result | bitwise shift left of a long *value1* by int *value2* positions | | lshr | 7b | 0111 1011 | | value1, value2 → result | bitwise shift right of a long *value1* by int *value2* positions | | lstore | 37 | 0011 0111 | 1: index | value → | store a long *value* in a local variable *#index* | | lstore_0 | 3f | 0011 1111 | | value → | store a long *value* in a local variable 0 | | lstore_1 | 40 | 0100 0000 | | value → | store a long *value* in a local variable 1 | | lstore_2 | 41 | 0100 0001 | | value → | store a long *value* in a local variable 2 | | lstore_3 | 42 | 0100 0010 | | value → | store a long *value* in a local variable 3 | | lsub | 65 | 0110 0101 | | value1, value2 → result | subtract two longs | | lushr | 7d | 0111 1101 | | value1, value2 → result | bitwise shift right of a long *value1* by int *value2* positions, unsigned | | lxor | 83 | 1000 0011 | | value1, value2 → result | bitwise XOR of two longs | | monitorenter | c2 | 1100 0010 | | objectref → | enter monitor for object ("grab the lock" – start of synchronized() section) | | monitorexit | c3 | 1100 0011 | | objectref → | exit monitor for object ("release the lock" – end of synchronized() section) | | multianewarray | c5 | 1100 0101 | 3: indexbyte1, indexbyte2, dimensions | count1, [count2,...] → arrayref | create a new array of *dimensions* dimensions of type identified by class reference in constant pool *index* (indexbyte1 << 8 \| indexbyte2); the sizes of each dimension is identified by *count1*, [*count2*, etc.] | | new | bb | 1011 1011 | 2: indexbyte1, indexbyte2 | → objectref | create new object of type identified by class reference in constant pool *index* (indexbyte1 << 8 \| indexbyte2) | | newarray | bc | 1011 1100 | 1: atype | count → arrayref | create new array with *count* elements of primitive type identified by *atype* | | nop | 00 | 0000 0000 | | [No change] | perform no operation | | pop | 57 | 0101 0111 | | value → | discard the top value on the stack | | pop2 | 58 | 0101 1000 | | {value2, value1} → | discard the top two values on the stack (or one value, if it is a double or long) | | putfield | b5 | 1011 0101 | 2: indexbyte1, indexbyte2 | objectref, value → | set field to *value* in an object *objectref*, where the field is identified by a field reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | putstatic | b3 | 1011 0011 | 2: indexbyte1, indexbyte2 | value → | set static field to *value* in a class, where the field is identified by a field reference *index* in constant pool (indexbyte1 << 8 \| indexbyte2) | | ret | a9 | 1010 1001 | 1: index | [No change] | continue execution from address taken from a local variable *#index* (the asymmetry with jsr is intentional) | | return | b1 | 1011 0001 | | → [empty] | return void from method | | saload | 35 | 0011 0101 | | arrayref, index → value | load short from array | | sastore | 56 | 0101 0110 | | arrayref, index, value → | store short to array | | sipush | 11 | 0001 0001 | 2: byte1, byte2 | → value | push a short onto the stack as an integer *value* | | swap | 5f | 0101 1111 | | value2, value1 → value1, value2 | swaps two top words on the stack (note that value1 and value2 must not be double or long) | | tableswitch | aa | 1010 1010 | 16+: [0–3 bytes padding], defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, lowbyte1, lowbyte2, lowbyte3, lowbyte4, highbyte1, highbyte2, highbyte3, highbyte4, jump offsets... | index → | continue execution from an address in the table at offset *index* | | wide | c4 | 1100 0100 | 3/5: opcode, indexbyte1, indexbyte2 or iinc, indexbyte1, indexbyte2, countbyte1, countbyte2 | [same as for corresponding instructions] | execute *opcode*, where *opcode* is either iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret, but assume the *index* is 16 bit; or execute iinc, where the *index* is 16 bits and the constant to increment by is a signed 16 bit short | | *(no name)* | cb-fd | | | | these values are currently unassigned for opcodes and are reserved for future use | © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏