java 字节码指令

转:http://blog.csdn.net/coslay/article/details/43131645


字节码格式

字节码是JVM的机器语言。JVM加载类文件时,对类中的每个方法,它都会得到一个字节码流。这些字节码流保存在JVM的方法区中。在程序运行过程中,当一个方法被调用时,它的字节码流就会被执行。根据特定JVM设计者的选择,它们可以通过解释的方式,即时编译(Just-in-time compilation)的方式或其他技术的方式被执行。

方法的字节码流就是JVM的指令(instruction)序列。每条指令包含一个单字节的操作码(opcode)和0个或多个操作数(operand)。操作码指明要执行的操作。如果JVM在执行操作前,需要更多的信息,这些信息会以0个或多个操作数的方式,紧跟在操作码的后面。

每种类型的操作码都有一个助记符(mnemonic)。类似典型的汇编语言风格,Java字节码流可以用它们的助记符和紧跟在后面的操作数来表示。例如,下面的字节码流可以分解成多个助记符的形式。

  1. // 字节码流:  03 3b  84  00  01 1a  05  68 3b a7 ff f9
  2. // 分解后:
  3. iconst_0      //  03
  4. istore_0      // 3b
  5. iinc  01     //  84  00  01
  6. iload_0       // 1a
  7. iconst_2      //  05
  8. imul          //  68
  9. istore_0      // 3b
  10. goto  -7       // a7 ff f9

字节码指令集被设计的很紧凑。除了处理跳表的2条指令以外,所有的指令都以字节边界对齐。操作码的总数很少,一个字节就能搞定。这最小化了JVM加载前,通过网络传输的类文件的大小;也使得JVM可以维持很小的实现。

JVM中,所有的计算都是围绕栈(stack)而展开的。因为JVM没有存储任意数值的寄存器(register),所有的操作数在计算开始之前,都必须先压入栈中。因此,字节码指令主要是用来操作栈的。例如,在上面的字节码序列中,通过iload_0先把本地变量(local variable)入栈,然后用iconst_2把数字2入栈的方式,来计算本地变量乘以2。两个整数都入栈之后,imul指令有效的从栈中弹出它们,然后做乘法,最后把运算结果压入栈中。istore_0指令把结果从栈顶弹出,保存回本地变量。JVM被设计成基于栈,而不是寄存器的机器,这使得它在如80486寄存器架构不佳的处理器上,也能被高效的实现。

原始类型(primitive types)

JVM支持7种原始数据类型。Java程序员可以声明和使用这些数据类型的变量,而Java字节码,处理这些数据类型。下表列出了这7种原始数据类型:

类型
定义
byte 单字节有符号二进制补码整数
short 2字节有符号二进制补码整数
int 4字节有符号二进制补码整数
long 8字节有符号二进制补码整数
float 4字节IEEE 754单精度浮点数
double 8字节IEEE 754双精度浮点数
char 2字节无符号Unicode字符

原始数据类型以操作数的方式出现在字节码流中。所有长度超过1字节的原始类型,都以大端(big-endian)的方式保存在字节码流中,这意味着高位字节出现在低位字节之前。例如,为了把常量值256(0x0100)压入栈中,你可以用sipush操作码,后跟一个短操作数。短操作数会以“01 00”的方式出现在字节码流中,因为JVM是大端的。如果JVM是小端(little-endian)的,短操作数将会是“00 01”。

  1. // Bytecode stream:  17  01  00
  2. // Dissassembly:
  3. sipush  256;      //  17  01  00

把常量(constants)压入栈中

很多操作码都可以把常量压入栈中。操作码以3中不同的方式指定入栈的常量值:由操作码隐式指明,作为操作数跟在操作码之后,或者从常量池(constant pool)中获取。

有些操作码本身就指明了要入栈的数据类型和常量数值。例如,iconst_1告诉JVM把整数1压入栈中。这种操作码,是为不同类型而经常入栈的数值而定义的。它们在字节码流中只占用1个字节,增进了字节码的执行效率,并减小了字节码流的大小。下表列出了int型和float型的操作码:

操作码
操作数
描述
iconst_m1 (none) pushes int -1 onto the stack
iconst_0 (none) pushes int 0 onto the stack
iconst_1 (none) pushes int 1 onto the stack
iconst_2 (none) pushes int 2 onto the stack
iconst_3 (none) pushes int 3 onto the stack
iconst_4 (none) pushes int 4 onto the stack
iconst_5 (none) pushes int 5 onto the stack
fconst_0 (none) pushes float 0 onto the stack
fconst_1 (none) pushes float 1 onto the stack
fconst_2 (none) pushes float 2 onto the stack

下面列出的操作码处理的int型和float型都是32位的值。Java栈单元(slot)是32位宽的,因此,每次一个int数和float数入栈,它都占用一个单元。下表列出的操作码处理long型和double型。long型和double型的数值占用64位。每次一个long数或double数被压入栈中,它都占用2个栈单元。下面的表格,列出了隐含处理long型和double型的操作码

操作码
操作数
描述
lconst_0 (none) pushes long 0 onto the stack
lconst_1 (none) pushes long 1 onto the stack
dconst_0 (none) pushes double 0 onto the stack
dconst_1 (none) pushes double 1 onto the stack

另外还有一个隐含入栈常量值的操作码,aconst_null,它把空对象(null object)的引用(reference)压入栈中。对象引用的格式取决于JVM实现。对象引用指向垃圾收集堆(garbage-collected heap)中的对象。空对象引用,意味着一个变量当前没有指向任何合法对象。aconst_null操作码用在给引用变量赋null值的时候。

操作码
操作数
描述
aconst_null (none) pushes a null object reference onto the stack

有2个操作码需要紧跟一个操作数来指明入栈的常量值。下表列出的操作码,用来把合法的byte型和short型的常量值压入栈中。byte型或short型的值在入栈之前,先被扩展成int型的值,因为栈单元是32位宽的。对byte型和short型的操作,实际上是基于它们扩展后的int型值的。

操作码
操作数
描述
bipush byte1 expands byte1 (a byte type) to an int and pushes it onto the stack
sipush byte1, byte2 expands byte1, byte2 (a short type) to an int and pushes it onto the stack

有3个操作码把常量池中的常量值压入栈中。所有和类关联的常量,如final变量,都被保存在类的常量池中。把常量池中的常量压入栈中的操作码,都有一个操作数,它表示需要入栈的常量在常量池中的索引。JVM会根据索引查找常量,确定它的类型,并把它压入栈中。

在字节码流中,常量池索引(constant pool index)是一个紧跟在操作码后的无符号值。操作码lcd1和lcd2把32位的项压入栈中,如int或float。两者的区别在于lcd1只适用于1-255的常量池索引位,因为它的索引只有1个字节。(常量池0号位未被使用。)lcd2的索引有2个字节,所以它可以适用于常量池的任意位置。lcd2w也有一个2字节的索引,它被用来指示任意含有64位的long或double型数据的常量池位置。下表列出了把常量池中的常量压入栈中的操作码:

操作码
操作数
描述
ldc1 indexbyte1 pushes 32-bit constant_pool entry specified by indexbyte1 onto the stack
ldc2 indexbyte1, indexbyte2 pushes 32-bit constant_pool entry specified by indexbyte1, indexbyte2 onto the stack
ldc2w indexbyte1, indexbyte2 pushes 64-bit constant_pool entry specified by indexbyte1,indexbyte2 onto the stack

把局部变量(local variables)压入栈中

局部变量保存在栈帧的一个特殊区域中。栈帧是当前执行方法正在使用的栈区。每个栈帧包含3个部分:本地变量区,执行环境和操作数栈区。把本地变量入栈实际上包含了把数值从栈帧的本地变量区移动到操作数栈区。操作数栈区总是在栈的顶部,所以,把一个值压到当前栈帧的操作数栈区顶部,跟压到整个JVM栈的顶部是一个意思。

Java栈是一个先进后出(LIFO)的32位宽的栈。所有的本地变量至少占用32位,因为栈中的每个单元都是32位宽的。像long和double类型的64位的本地变量会占用2个栈单元。byte和short型的本地变量会当做int型来存储,但只拥有较小类型的合法值。例如,表示byte型的int型本地变量取值范围总是-128到127。

每个本地变量都有一个唯一索引。方法栈帧的本地变量区,可以当成是一个拥有32位宽的元素的数组,每个元素都可以用数组索引来寻址。long和double型的占用2个单元的本地变量,且用低位元素的索引寻址。例如,对一个占用2单元和3单元的double数值,会用索引2来引用。

有一些操作码可以把int和float型本地变量压入操作数栈。部分操作码,定义成隐含常用本地变量地址的引用。例如,iload_0加载处在位置0的int型本地变量。其他本地变量,通过操作码后跟一个字节的本地变量索引的方式压入栈中。iload指令就是这种操作码类型的一个例子。iload后的一个字节被解释成指向本地变量的8位无符号索引。

类似iload所用的8位无符号本地变量索引,限制了一个方法最多只能有256个本地变量。有一个单独的wide指令可以把8位索引扩展为16位索引,则使得本地变量数的上限提高到64k个。操作码wide只有1个操作数。wide和它的操作数,出现在像iload之类的有一个8位无符号本地变量索引的指令之前。JVM会把wide的操作数和iload的操作数合并为一个16位的无符号本地变量索引。

下表列出了把int和float型本地变量压入栈中的操作码:

操作码
操作数
描述
iload vindex pushes int from local variable position vindex
iload_0 (none) pushes int from local variable position zero
iload_1 (none) pushes int from local variable position one
iload_2 (none) pushes int from local variable position two
iload_3 (none) pushes int from local variable position three
fload vindex pushes float from local variable position vindex
fload_0 (none) pushes float from local variable position zero
fload_1 (none) pushes float from local variable position one
fload_2 (none) pushes float from local variable position two
fload_3 (none) pushes float from local variable position three

接下来的这张表,列出了把long和double型本地变量压入栈中的指令。这些指令把64位的数从栈帧的本地变量区移动到操作数区。

操作码
操作数
描述
lload vindex pushes long from local variable positions vindex and (vindex + 1)
lload_0 (none) pushes long from local variable positions zero and one
lload_1 (none) pushes long from local variable positions one and two
lload_2 (none) pushes long from local variable positions two and three
lload_3 (none) pushes long from local variable positions three and four
dload vindex pushes double from local variable positions vindex and (vindex + 1)
dload_0 (none) pushes double from local variable positions zero and one
dload_1 (none) pushes double from local variable positions one and two
dload_2 (none) pushes double from local variable positions two and three
dload_3 (none) pushes double from local variable positions three and four

最后一组操作码,把32位的对象引用从栈帧的本地变量区移动到操作数区。如下表:

操作码
操作数
描述
aload vindex pushes object reference from local variable position vindex
aload_0 (none) pushes object reference from local variable position zero
aload_1 (none) pushes object reference from local variable position one
aload_2 (none) pushes object reference from local variable position two
aload_3 (none) pushes object reference from local variable position three

弹出到本地变量

每一个将局部变量压入栈中的操作码,都有一个对应的负责弹出栈顶元素到本地变量中的操作码。这些操作码的名字可以通过替换入栈操作码名中的“load”为“store”得到。下表列出了将int和float型数值弹出操作数栈到本地变量中的操作码。这些操作码将一个32位的值从栈顶移动到本地变量中。

操作码
操作数
描述
istore vindex pops int to local variable position vindex
istore_0 (none) pops int to local variable position zero
istore_1 (none) pops int to local variable position one
istore_2 (none) pops int to local variable position two
istore_3 (none) pops int to local variable position three
fstore vindex pops float to local variable position vindex
fstore_0 (none) pops float to local variable position zero
fstore_1 (none) pops float to local variable position one
fstore_2 (none) pops float to local variable position two
fstore_3 (none) pops float to local variable position three

下一张表中,展示了负责将long和double类型数值出栈并存到局部变量的字节码指令,这些指令将64位的值从操作数栈顶移动到本地变量中。

操作码
操作数
描述
lstore vindex pops long to local variable positions vindex and (vindex + 1)
lstore_0 (none) pops long to local variable positions zero and one
lstore_1 (none) pops long to local variable positions one and two
lstore_2 (none) pops long to local variable positions two and three
lstore_3 (none) pops long to local variable positions three and four
dstore vindex pops double to local variable positions vindex and (vindex + 1)
dstore_0 (none) pops double to local variable positions zero and one
dstore_1 (none) pops double to local variable positions one and two
dstore_2 (none) pops double to local variable positions two and three
dstore_3 (none) pops double to local variable positions three and four

最后一组操作码,负责将32位的对象引用从操作数栈顶移动到本地变量中。

操作码
操作数
描述
astore vindex pops object reference to local variable position vindex
astore_0 (none) pops object reference to local variable position zero
astore_1 (none) pops object reference to local variable position one
astore_2 (none) pops object reference to local variable position two
astore_3 (none) pops object reference to local variable position three

类型转换

JVM中有一些操作码用来将一种基本类型的数值转换成另外一种。字节码流中的转换操作码后面不跟操作数,被转换的值取自栈顶。JVM弹出栈顶的值,转换后再将结果压入栈中。下表列出了在int,long,float和double间转换的操作码。这四种类型组合的每一个可能的转换,都有一个对应的操作码。

操作码
操作数
描述
i2l (none) converts int to long
i2f (none) converts int to float
i2d (none) converts int to double
l2i (none) converts long to int
l2f (none) converts long to float
l2d (none) converts long to double
f2i (none) converts float to int
f2l (none) converts float to long
f2d (none) converts float to double
d2i (none) converts double to int
d2l (none) converts double to long
d2f (none) converts double to float

下表列出了将int型转换为更小类型的操作码。不存在直接将long,float,double型转换为比int型小的类型的操作码。因此,像float到byte这样的转换,需要两步。第一步,f2i将float转换为int,第二步,int2byte操作码将int转换为byte。

操作码
操作数
描述
int2byte (none) converts int to byte
int2char (none) converts int to char
int2short (none) converts int to short

虽然存在将int转换为更小类型(byte,short,char)的操作码,但是不存在反向转换的操作码。这是因为byte,short和char型的数值在入栈之前会转换成int型。byte,short和char型数值的算术运算,首先要将这些类型的值转为int,然后执行算术运算,最后得到int型结果。也就是说,如果两个byte型的数相加,会得到一个int型的结果,如果你想要byte型的结果,你必须显式地将int类型的结果转换为byte类型的值。例如,下面的代码编译出错:

  1. class BadArithmetic  {
  2.      byte addOneAndOne ( )  {
  3.          byte a =  1 ;
  4.          byte b =  1 ;
  5.          byte c = a + b ;
  6.          return c ;
  7.      }
  8. }

javac会对上面的代码给出如下错误:

  1. BadArithmetic.java ( 7 ): Incompatible type  for declaration.
  2. Explicit cast needed to convert int to byte.
  3.                 byte c = a + b;
  4.                      ^

Java程序员必须显式的把a + b的结果转换为byte,这样才能通过编译。

  1. class GoodArithmetic  {
  2.      byte addOneAndOne ( )  {
  3.          byte a =  1 ;
  4.          byte b =  1 ;
  5.          byte c =  ( byte )  (a + b ) ;
  6.          return c ;
  7.      }
  8. }

这样,javac会很高兴的生成GoodArithmetic.class文件,它包含如下的addOneAndOne()方法的字节码序列:

  1. iconst_1  // Push int constant  1.
  2. istore_1  // Pop into local variable  1, which is a: byte a =  1;
  3. iconst_1  // Push int constant  1 again.
  4. istore_2  // Pop into local variable  2, which is b: byte b =  1;
  5. iload_1   // Push a  (a is already stored as an int  in local variable  1 ).
  6. iload_2   // Push b  (b is already stored as an int  in local variable  2 ).
  7. iadd      // Perform addition. Top of stack is now  (a + b ), an int.
  8. int2byte  // Convert int result to byte  (result still occupies  32 bits ).
  9. istore_3  // Pop into local variable  3, which is byte c: byte c =  (byte )  (a + b );
  10. iload_3   // Push the value of c so it can be returned.
  11. ireturn   // Proudly return the result of the addition: return c;

本文译自:Bytecode basics


转载自:http://iofree.cc/%E5%AD%97%E8%8A%82%E7%A0%81%E5%9F%BA%E7%A1%80%EF%BC%9Ajvm%E5%AD%97%E8%8A%82%E7%A0%81%E5%88%9D%E6%8E%A2/

Mnemonic Opcode
(in hex)
Other bytes Stack
[before]→[after]
Description
aaload32 arrayref, index → valueload onto the stack a reference from an array
aastore53 arrayref, index, value →store into a reference in an array
aconst_null01 → nullpush a null reference onto the stack
aload191: index→ objectrefload a reference onto the stack from a local variable #index
aload_02a → objectrefload a reference onto the stack from local variable 0
aload_12b → objectrefload a reference onto the stack from local variable 1
aload_22c → objectrefload a reference onto the stack from local variable 2
aload_32d → objectrefload a reference onto the stack from local variable 3
anewarraybd2: indexbyte1, indexbyte2count → arrayrefcreate a new array of references of length count and component type identified by the class referenceindex (indexbyte1 << 8 + indexbyte2) in the constant pool
areturnb0 objectref → [empty]return a reference from a method
arraylengthbe arrayref → lengthget the length of an array
astore3a1: indexobjectref →store a reference into a local variable #index
astore_04b objectref →store a reference into local variable 0
astore_14c objectref →store a reference into local variable 1
astore_24d objectref →store a reference into local variable 2
astore_34e objectref →store a reference into local variable 3
athrowbf objectref → [empty], objectrefthrows an error or exception (notice that the rest of the stack is cleared, leaving only a reference to the Throwable)
baload33 arrayref, index → valueload a byte or Boolean value from an array
bastore54 arrayref, index, value →store a byte or Boolean value into an array
bipush101: byte→ valuepush a byte onto the stack as an integer value
breakpointca  reserved for breakpoints in Java debuggers; should not appear in any class file
caload34 arrayref, index → valueload a char from an array
castore55 arrayref, index, value →store a char into an array
checkcastc02: indexbyte1, indexbyte2objectref → objectrefchecks whether an objectref is of a certain type, the class reference of which is in the constant pool at index (indexbyte1 << 8 + indexbyte2)
d2f90 value → resultconvert a double to a float
d2i8e value → resultconvert a double to an int
d2l8f value → resultconvert a double to a long
dadd63 value1, value2 → resultadd two doubles
daload31 arrayref, index → valueload a double from an array
dastore52 arrayref, index, value →store a double into an array
dcmpg98 value1, value2 → resultcompare two doubles
dcmpl97 value1, value2 → resultcompare two doubles
dconst_00e → 0.0push the constant 0.0 onto the stack
dconst_10f → 1.0push the constant 1.0 onto the stack
ddiv6f value1, value2 → resultdivide two doubles
dload181: index→ valueload a double value from a local variable #index
dload_026 → valueload a double from local variable 0
dload_127 → valueload a double from local variable 1
dload_228 → valueload a double from local variable 2
dload_329 → valueload a double from local variable 3
dmul6b value1, value2 → resultmultiply two doubles
dneg77 value → resultnegate a double
drem73 value1, value2 → resultget the remainder from a division between two doubles
dreturnaf value → [empty]return a double from a method
dstore391: indexvalue →store a double value into a local variable #index
dstore_047 value →store a double into local variable 0
dstore_148 value →store a double into local variable 1
dstore_249 value →store a double into local variable 2
dstore_34a value →store a double into local variable 3
dsub67 value1, value2 → resultsubtract a double from another
dup59 value → value, valueduplicate the value on top of the stack
dup_x15a value2, value1 → value1, value2, value1insert 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_x25b value3, value2, value1 → value1, value3, value2, value1insert 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
dup25c {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_x15d value3, {value2, value1} → {value2, value1}, value3, {value2, value1}duplicate two words and insert beneath third word (see explanation above)
dup2_x25e {value4, value3}, {value2, value1} → {value2, value1}, {value4, value3}, {value2, value1}duplicate two words and insert beneath fourth word
f2d8d value → resultconvert a float to a double
f2i8b value → resultconvert a float to an int
f2l8c value → resultconvert a float to a long
fadd62 value1, value2 → resultadd two floats
faload30 arrayref, index → valueload a float from an array
fastore51 arrayref, index, value →store a float in an array
fcmpg96 value1, value2 → resultcompare two floats
fcmpl95 value1, value2 → resultcompare two floats
fconst_00b → 0.0fpush 0.0f on the stack
fconst_10c → 1.0fpush 1.0f on the stack
fconst_20d → 2.0fpush 2.0f on the stack
fdiv6e value1, value2 → resultdivide two floats
fload171: index→ valueload a float value from a local variable #index
fload_022 → valueload a float value from local variable 0
fload_123 → valueload a float value from local variable 1
fload_224 → valueload a float value from local variable 2
fload_325 → valueload a float value from local variable 3
fmul6a value1, value2 → resultmultiply two floats
fneg76 value → resultnegate a float
frem72 value1, value2 → resultget the remainder from a division between two floats
freturnae value → [empty]return a float
fstore381: indexvalue →store a float value into a local variable #index
fstore_043 value →store a float value into local variable 0
fstore_144 value →store a float value into local variable 1
fstore_245 value →store a float value into local variable 2
fstore_346 value →store a float value into local variable 3
fsub66 value1, value2 → resultsubtract two floats
getfieldb42: index1, index2objectref → valueget a field value of an object objectref, where the field is identified by field reference in the constant pool index (index1 << 8 + index2)
getstaticb22: index1, index2→ valueget a static field value of a class, where the field is identified by field reference in the constant pool index (index1 << 8 + index2)
gotoa72: branchbyte1, branchbyte2[no change]goes to another instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
goto_wc84: 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)
i2b91 value → resultconvert an int into a byte
i2c92 value → resultconvert an int into a character
i2d87 value → resultconvert an int into a double
i2f86 value → resultconvert an int into a float
i2l85 value → resultconvert an int into a long
i2s93 value → resultconvert an int into a short
iadd60 value1, value2 → resultadd two ints
iaload2e arrayref, index → valueload an int from an array
iand7e value1, value2 → resultperform a bitwise and on two integers
iastore4f arrayref, index, value →store an int into an array
iconst_m102 → -1load the int value -1 onto the stack
iconst_003 → 0load the int value 0 onto the stack
iconst_104 → 1load the int value 1 onto the stack
iconst_205 → 2load the int value 2 onto the stack
iconst_306 → 3load the int value 3 onto the stack
iconst_407 → 4load the int value 4 onto the stack
iconst_508 → 5load the int value 5 onto the stack
idiv6c value1, value2 → resultdivide two integers
if_acmpeqa52: branchbyte1, branchbyte2value1, value2 →if references are equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
if_acmpnea62: branchbyte1, branchbyte2value1, value2 →if references are not equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
if_icmpeq9f2: branchbyte1, branchbyte2value1, value2 →if ints are equal, branch to instruction at branchoffset (signed short constructed from unsigned bytesbranchbyte1 << 8 + branchbyte2)
if_icmpgea22: branchbyte1, branchbyte2value1, 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_icmpgta32: branchbyte1, branchbyte2value1, value2 →if value1 is greater than value2, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
if_icmplea42: branchbyte1, branchbyte2value1, 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_icmplta12: branchbyte1, branchbyte2value1, value2 →if value1 is less than value2, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
if_icmpnea02: branchbyte1, branchbyte2value1, value2 →if ints are not equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
ifeq992: branchbyte1, branchbyte2value →if value is 0, branch to instruction at branchoffset (signed short constructed from unsigned bytesbranchbyte1 << 8 + branchbyte2)
ifge9c2: branchbyte1, branchbyte2value →if value is greater than or equal to 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
ifgt9d2: branchbyte1, branchbyte2value →if value is greater than 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
ifle9e2: branchbyte1, branchbyte2value →if value is less than or equal to 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
iflt9b2: branchbyte1, branchbyte2value →if value is less than 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
ifne9a2: branchbyte1, branchbyte2value →if value is not 0, branch to instruction at branchoffset (signed short constructed from unsigned bytesbranchbyte1 << 8 + branchbyte2)
ifnonnullc72: branchbyte1, branchbyte2value →if value is not null, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
ifnullc62: branchbyte1, branchbyte2value →if value is null, branch to instruction at branchoffset (signed short constructed from unsigned bytesbranchbyte1 << 8 + branchbyte2)
iinc842: index, const[No change]increment local variable #index by signed byte const
iload151: index→ valueload an int value from a local variable #index
iload_01a → valueload an int value from local variable 0
iload_11b → valueload an int value from local variable 1
iload_21c → valueload an int value from local variable 2
iload_31d → valueload an int value from local variable 3
impdep1fe  reserved for implementation-dependent operations within debuggers; should not appear in any class file
impdep2ff  reserved for implementation-dependent operations within debuggers; should not appear in any class file
imul68 value1, value2 → resultmultiply two integers
ineg74 value → resultnegate int
instanceofc12: indexbyte1, indexbyte2objectref → resultdetermines if an object objectref is of a given type, identified by class reference index in constant pool (indexbyte1 << 8 + indexbyte2)
invokedynamicba4: indexbyte1, indexbyte2, 0, 0[arg1, [arg2 ...]] →invokes a dynamic method identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2)
invokeinterfaceb94: indexbyte1, indexbyte2, count, 0objectref, [arg1, arg2, ...] →invokes an interface method on object objectref, where the interface method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2)
invokespecialb72: indexbyte1, indexbyte2objectref, [arg1, arg2, ...] →invoke instance method on object objectref, where the method is identified by method reference indexin constant pool (indexbyte1 << 8 + indexbyte2)
invokestaticb82: indexbyte1, indexbyte2[arg1, arg2, ...] →invoke a static method, where the method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2)
invokevirtualb62: indexbyte1, indexbyte2objectref, [arg1, arg2, ...] →invoke virtual method on object objectref, where the method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2)
ior80 value1, value2 → resultbitwise int or
irem70 value1, value2 → resultlogical int remainder
ireturnac value → [empty]return an integer from a method
ishl78 value1, value2 → resultint shift left
ishr7a value1, value2 → resultint arithmetic shift right
istore361: indexvalue →store int value into variable #index
istore_03b value →store int value into variable 0
istore_13c value →store int value into variable 1
istore_23d value →store int value into variable 2
istore_33e value →store int value into variable 3
isub64 value1, value2 → resultint subtract
iushr7c value1, value2 → resultint logical shift right
ixor82 value1, value2 → resultint xor
jsra82: branchbyte1, branchbyte2→ addressjump to subroutine at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) and place the return address on the stack
jsr_wc94: branchbyte1, branchbyte2, branchbyte3, branchbyte4→ addressjump 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
l2d8a value → resultconvert a long to a double
l2f89 value → resultconvert a long to a float
l2i88 value → resultconvert a long to a int
ladd61 value1, value2 → resultadd two longs
laload2f arrayref, index → valueload a long from an array
land7f value1, value2 → resultbitwise and of two longs
lastore50 arrayref, index, value →store a long to an array
lcmp94 value1, value2 → resultcompare two longs values
lconst_009 → 0Lpush the long 0 onto the stack
lconst_10a → 1Lpush the long 1 onto the stack
ldc121: index→ valuepush a constant #index from a constant pool (String, int or float) onto the stack
ldc_w132: indexbyte1, indexbyte2→ valuepush a constant #index from a constant pool (String, int or float) onto the stack (wide index is constructed as indexbyte1 << 8 + indexbyte2)
ldc2_w142: indexbyte1, indexbyte2→ valuepush a constant #index from a constant pool (double or long) onto the stack (wide index is constructed as indexbyte1 << 8 + indexbyte2)
ldiv6d value1, value2 → resultdivide two longs
lload161: index→ valueload a long value from a local variable #index
lload_01e → valueload a long value from a local variable 0
lload_11f → valueload a long value from a local variable 1
lload_220 → valueload a long value from a local variable 2
lload_321 → valueload a long value from a local variable 3
lmul69 value1, value2 → resultmultiply two longs
lneg75 value → resultnegate a long
lookupswitchab4+: <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
lor81 value1, value2 → resultbitwise or of two longs
lrem71 value1, value2 → resultremainder of division of two longs
lreturnad value → [empty]return a long value
lshl79 value1, value2 → resultbitwise shift left of a long value1 by value2 positions
lshr7b value1, value2 → resultbitwise shift right of a long value1 by value2 positions
lstore371: indexvalue →store a long value in a local variable #index
lstore_03f value →store a long value in a local variable 0
lstore_140 value →store a long value in a local variable 1
lstore_241 value →store a long value in a local variable 2
lstore_342 value →store a long value in a local variable 3
lsub65 value1, value2 → resultsubtract two longs
lushr7d value1, value2 → resultbitwise shift right of a long value1 by value2 positions, unsigned
lxor83 value1, value2 → resultbitwise exclusive or of two longs
monitorenterc2 objectref →enter monitor for object ("grab the lock" - start of synchronized() section)
monitorexitc3 objectref →exit monitor for object ("release the lock" - end of synchronized() section)
multianewarrayc53: indexbyte1, indexbyte2, dimensionscount1, [count2,...] → arrayrefcreate 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 bycount1, [count2, etc.]
newbb2: indexbyte1, indexbyte2→ objectrefcreate new object of type identified by class reference in constant pool index (indexbyte1 << 8 + indexbyte2)
newarraybc1: atypecount → arrayrefcreate new array with count elements of primitive type identified by atype
nop00 [No change]perform no operation
pop57 value →discard the top value on the stack
pop258 {value2, value1} →discard the top two values on the stack (or one value, if it is a double or long)
putfieldb52: indexbyte1, indexbyte2objectref, 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)
putstaticb32: indexbyte1, indexbyte2value →set static field to value in a class, where the field is identified by a field reference index in constant pool (indexbyte1 << 8 + indexbyte2)
reta91: index[No change]continue execution from address taken from a local variable #index (the asymmetry with jsr is intentional)
returnb1 → [empty]return void from method
saload35 arrayref, index → valueload short from array
sastore56 arrayref, index, value →store short to array
sipush112: byte1, byte2→ valuepush a short onto the stack
swap5f value2, value1 → value1, value2swaps two top words on the stack (note that value1 and value2 must not be double or long)
tableswitchaa4+: [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
widec43/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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值