Preface notes

This article introduces the bytecode sources and the compilation and decompilation processes, as well as common bytecode instructions

Java files become class files

Java files become class files, depending on the javac command. For example, we write a Java file hello.java

The class file is generated by executing the following command:

Javac hello. Java generates Hello.class

If hello. Java references the Test class, execute the following command:

Javac test.java hello. Java generates test.class hello.class

2. View the class file

(1) use XXD Hello(.class) to view the class file, all hexadecimal form
(2) Through the javap (-c -v -p L) command view is a series of instructions, this is more easy to understand

Class file composition

The resulting.class file consists of the following sections: CAFEBABE is the file identifier, indicating that it is a class file, followed by the compiled version, number of constant pools, class access tags, interfaces, member variables, number of methods, attributes, etc.


Principle of bytecode

First, a few concepts:

Stack frames: Stack frames are created as the method is created and destroyed as the method ends. Each stack frame has its own local variable table and operand stack

Local variable table: store the parameters and temporary variables needed by the method

Operand stack: it is taken from the local variable table to the top of the stack and stored from the top of the stack to the local variable table, which needs to be used together with instructions


Bytecode instructions

Bytecode instructions take up two bytes, which means a maximum of 256, of which 200+ have been used so far

There are several types of instructions:

  • Load and store instructions: For example, ILoAD loads an integer value from a local variator into the operand stack
  • Control transfer instructions: such as conditional branch IFEQ
  • Object operations: such as the instruction new to create class instances
  • Method invocation: For example, the Invokevirtual directive is used to invoke an instance method of an object
  • Operation instructions and type conversions: such as the addition instruction iadd
  • Thread synchronization, monitorenter and Monitorexit directives support the semantics of the synchronized keyword
  • Exception handling: For example, athrow explicitly throws an exception

6. Bytecode overview

The bytecode mnemonics Instruction meaning
0x00 nop None
0x01 aconst_null Push NULL to the top of the stack
0x02 iconst_m1 Push int -1 to the top of the stack
0x03 iconst_0 Push int 0 to the top of the stack
0x04 iconst_1 Push int 1 to the top of the stack
0x05 iconst_2 Push int 2 to the top of the stack
0x06 iconst_3 Push int 3 to the top of the stack
0x07 iconst_4 Push int 4 to the top of the stack
0x08 iconst_5 Push int 5 to the top of the stack
0x09 lconst_0 Push long 0 to the top of the stack
0x0a lconst_1 Push long 1 to the top of the stack
0x0b fconst_0 Push type float 0 to the top of the stack
0x0c fconst_1 Push type float 1 to the top of the stack
0x0d fconst_2 Push type float 2 to the top of the stack
0x0e dconst_0 Push double 0 to the top of the stack
0x0f dconst_1 Push double 1 to the top of the stack
0x10 bipush Push constant values of a single byte (-128~127) to the top of the stack
0x11 sipush Push a short integer constant (-32768~32767) to the top of the stack
0x12 ldc Pushes int,float, or String constant values from the constant pool to the top of the stack
0x13 ldc_w Push int,float, or String constant values from the constant pool to the top of the stack (wide index)
0x14 ldc2_w Push a long or double constant value from the constant pool to the top of the stack (wide index)
0x15 iload Pushes the specified local variable of type int to the top of the stack
0x16 lload Pushes the specified long local variable to the top of the stack
0x17 fload Pushes the specified local variable of type float to the top of the stack
0x18 dload Pushes the specified double local variable to the top of the stack
0x19 aload Pushes the specified reference type local variable to the top of the stack
0x1a iload_0 Push the first local variable of int to the top of the stack
0x1b iload_1 Push the second local variable of int to the top of the stack
0x1c iload_2 Push the third local variable of type int to the top of the stack
0x1d iload_3 Push the fourth local variable of int to the top of the stack
0x1e lload_0 Push the first long local variable to the top of the stack
0x1f lload_1 Push the second long local variable to the top of the stack
0x20 lload_2 Push the third long local variable to the top of the stack
0x21 lload_3 Push the fourth long local variable to the top of the stack
0x22 fload_0 Push the first local variable of type float to the top of the stack
0x23 fload_1 Push the second local variable of type float to the top of the stack
0x24 fload_2 Push the third local variable of type float to the top of the stack
0x25 fload_3 Push the fourth local variable of type float to the top of the stack
0x26 dload_0 Push the first double local variable to the top of the stack
0x27 dload_1 Push the second double local variable to the top of the stack
0x28 dload_2 Push the third double local variable to the top of the stack
0x29 dload_3 Push the fourth local variable of type double to the top of the stack
0x2a aload_0 Push the first reference type local variable to the top of the stack
0x2b aload_1 Push the second reference type local variable to the top of the stack
0x2c aload_2 Push the third reference type local variable to the top of the stack
0x2d aload_3 Push the fourth reference type local variable to the top of the stack
0x2e iaload Pushes the value of the specified index of an int to the top of the stack
0x2f laload Pushes the value of the specified index of the long array to the top of the stack
0x30 faload Pushes the value of the specified index of a float array to the top of the stack
0x31 daload Pushes the value of the specified index of an array double to the top of the stack
0x32 aaload Pushes the value of the specified index of the array of reference types to the top of the stack
0x33 baload Pushes the value of a Boolean or Byte array specified index to the top of the stack
0x34 caload Pushes the value of a char array to the top of the stack
0x35 saload Pushes the value of the specified index of the short array to the top of the stack
0x36 istore Stores the top int value to the specified local variable
0x37 lstore Stores the top of the stack long value to the specified local variable
0x38 fstore Stores the top stack float value to the specified local variable
0x39 dstore Stores the top of the stack double to the specified local variable
0x3a astore Stores the top of the stack reference type value into the specified local variable
0x3b istore_0 Store the top int value to the first local variable
0x3c istore_1 Store the top int value to the second local variable
0x3d istore_2 Store the top int value into the third local variable
0x3e istore_3 Store the top int value into the fourth local variable
0x3f lstore_0 Store the top of the stack value into the first local variable
0x40 lstore_1 Store the top of the stack long value into the second local variable
0x41 lstore_2 Store the top of the stack long value into the third local variable
0x42 lstore_3 Store the top of the stack long value into the fourth local variable
0x43 fstore_0 Store the top stack float value to the first local variable
0x44 fstore_1 Store the top stack float value into the second local variable
0x45 fstore_2 Store the top stack float value into the third local variable
0x46 fstore_3 Store the top stack float value into the fourth local variable
0x47 dstore_0 Store the top of the stack double to the first local variable
0x48 dstore_1 Store the top of the stack double to the second local variable
0x49 dstore_2 Store the top of the stack double into the third local variable
0x4a dstore_3 Store the top of the stack double into the fourth local variable
0x4b astore_0 Store the top of the stack reference value into the first local variable
0x4c astore_1 Store the top of the stack reference value into the second local variable
0x4d astore_2 Store the top of the stack reference value into a third local variable
0x4e astore_3 Store the top of the stack reference value into the fourth local variable
0x4f iastore Stores the top int into the specified index position of the specified array
0x50 lastore Stores the top long value to the specified index position in the specified array
0x51 fastore Stores the top float value to the specified index position of the specified array
0x52 dastore Stores the top double to the specified index position in the specified array
0x53 aastore Stores the top of the stack reference value to the specified index position of the specified array
0x54 bastore Stores the top stack Boolean or Byte value to the specified index position of the specified array
0x55 castore Stores the top char value to the specified index position in the specified array
0x56 sastore Stores the top short value to the specified index position in the specified array
0x57 pop Eject top value (value cannot be long or double)
0x58 pop2 Pops one (for non-long or double types) or two values at the top of the stack (for other types that are not long or double)
0x59 dup Copies the top value of the stack and pushes it to the top
0x5a dup_x1 Copies the top value of the stack and pushes the two replicated values to the top
0x5b dup_x2 Copy the top value and push three (or two) copy values to the top of the stack
0x5c dup2 Copy one (for long or double) or two (for other types that are not long or double) values to the top of the stack and push the copied value to the top
0x5d dup2_x1 Double version of the dup_x1 instruction
0x5e dup2_x2 Double version of the dup_x2 instruction
0x5f swap Swap the two values at the top of the stack (values cannot be long or double)
0x60 iadd Add two int values at the top of the stack and push the result to the top
0x61 ladd Add the top two longs and push the result to the top of the stack
0x62 fadd Add two float values at the top of the stack and push the result to the top
0x63 dadd Add the top two double values and push the result to the top of the stack
0x64 isub Subtract the top two int values and push the result to the top of the stack
0x65 lsub Subtract the top two longs and push the result to the top of the stack
0x66 fsub Subtract the top two float values and push the result to the top of the stack
0x67 dsub Subtract the top double and push the result to the top of the stack
0x68 imul Multiply the top two int values and push the result to the top of the stack
0x69 lmul Multiply the top two longs and push the result to the top of the stack
0x6a fmul Multiply the top two float values and push the result to the top of the stack
0x6b dmul Multiply the top two double values and push the result to the top of the stack
0x6c idiv Divide the top two int values and push the result to the top of the stack
0x6d ldiv Divide the top two longs and push the result to the top of the stack
0x6e fdiv Divide two float values at the top of the stack and push the result to the top
0x6f ddiv Divide the top double and push the result to the top of the stack
0x70 irem The two int values at the top of the stack are modelled and the results are pushed to the top of the stack
0x71 lrem The two long values at the top of the stack are used for modular operation and the result is pushed to the top of the stack
0x72 frem Modulo the top two float values and push the result to the top of the stack
0x73 drem Modulo operation is performed on the top two double values and the result is pushed to the top of the stack
0x74 ineg Take the top int value negative and push the result to the top of the stack
0x75 lneg Take the top long value negative and push the result to the top of the stack
0x76 fneg Take the top float value negative and push the result to the top of the stack
0x77 dneg Take the top double negative and push the result to the top of the stack
0x78 ishl Moves the value of int by the specified number of digits to the left and pushes the result to the top of the stack
0x79 lshl Moves the long value by the specified number of digits to the left and pushes the result to the top of the stack
0x7a ishr Moves the value of int (signed) right by the specified number of digits and pushes the result to the top of the stack
0x7b lshr Moves the long value (signed) right by the specified number of digits and pushes the result to the top of the stack
0x7c iushr Moves the value of int (unsigned) right by the specified number of digits and pushes the result to the top of the stack
0x7d lushr Moves the long value (unsigned) right by the specified number of digits and pushes the result to the top of the stack
0x7e iand Place the top two int values “bitwise and” and push the result to the top of the stack
0x7f land Push the top two longs “bitwise and” to the top of the stack
0x80 ior Place the top two int values “bitwise or” and push the result to the top of the stack
0x81 lor The top two longs are “bitwise or” and pushed to the top of the stack
0x82 ixor The top two int values are “bitwise xor” and pushed to the top of the stack
0x83 lxor The top two longs are “bitwise xor” and pushed to the top of the stack
0x84 iinc Increments a variable of type int to the specified value (I ++, I –, I +=2, etc.)
0x85 i2l Cast the top int value to a long value and push the result to the top of the stack
0x86 i2f Cast the top int value to a float value and push the result to the top of the stack
0x87 i2d Cast the top int to a double and push the result to the top of the stack
0x88 l2i Cast the top long value to an int value and push the result to the top of the stack
0x89 l2f Casts a top-of-stack long value to a float value and pushes the result to the top of the stack
0x8a l2d Casts the top long value to a double and pushes the result to the top of the stack
0x8b f2i Cast a top float value to an int value and push the result to the top of the stack
0x8c f2l Cast a top float value to a long value and push the result to the top of the stack
0x8d f2d Casts a top float value to a double and pushes the result to the top of the stack
0x8e d2i Casts a top double to an int and pushes the result to the top of the stack
0x8f d2l Casts a top double to a long and pushes the result to the top of the stack
0x90 d2f Casts a top double value to a float value and pushes the result to the top of the stack
0x91 i2b Casts a top-of-stack int value to a byte value and pushes the result to the top of the stack
0x92 i2c Cast top int to char and push the result to the top of the stack
0x93 i2s Cast top int to short and push the result to the top of the stack
0x94 lcmp Compare the two longs at the top of the stack and push the result (1, 0, or -1) to the top
0x95 fcmpl Compare two float values at the top of the stack and push the result (1, 0, or -1) to the top; When one of the values isNaN, push -1 to the top of the stack
0x96 fcmpg Compare two float values at the top of the stack and push the result (1, 0, or -1) to the top; When one of the values isNaN, push 1 to the top of the stack
0x97 dcmpl Compare two double values at the top of the stack and push the result (1, 0, or -1) to the top; When one of the values isNaN, push -1 to the top of the stack
0x98 dcmpg Compare two double values at the top of the stack and push the result (1, 0, or -1) to the top; When one of the values isNaN, push 1 to the top of the stack
0x99 ifeq Jump if the top value of int equals 0
0x9a ifne Jump if the top value of int does not equal 0
0x9b iflt Jump if the top value of int is less than 0
0x9c ifge Jump if the top value of int is greater than or equal to 0
0x9d ifgt Jump if the top value of int is greater than 0
0x9e ifle Jump if the top value of int is less than or equal to 0
0x9f if_icmpeq Compares two ints at the top of the stack, jumps when the result equals 0
0xa0 if_icmpne Compares two ints at the top of the stack, jumps if the result is not equal to 0
0xa1 if_icmplt Compare two ints at the top of the stack, jump if the result is less than 0
0xa2 if_icmpge Compares two int values at the top of the stack, jumps if the result is greater than or equal to 0
0xa3 if_icmpgt Compares two ints at the top of the stack, jumps if the result is greater than 0
0xa4 if_icmple Compare two ints at the top of the stack, jump if the result is less than or equal to 0
0xa5 if_acmpeq Compares two referential values at the top of the stack, jumps if the results are equal
0xa6 if_acmpne Compares two referential values at the top of the stack, jumps if the results are not equal
0xa7 goto Unconditional jump
0xa8 jsr Jumps to the specified 16-bit offset and pushes the address of the next JSR instruction to the top of the stack
0xa9 ret Returns the instruction location to the index specified by the local variable (usually used in conjunction with JSR or jSR_w)
0xaa tableswitch For switch conditional jump, case value continuous (variable length instruction)
0xab lookupswitch For switch conditional jump, case value discontinuous (variable length instruction)
0xac ireturn Returns an int from the current method
0xad lreturn Returns long from the current method
0xae freturn Returns float from the current method
0xaf dreturn Returns double from the current method
0xb0 areturn Returns an object reference from the current method
0xb1 return Returns void from the current method
0xb2 getstatic Gets the static field of the specified class and pushes it to the top of the stack
0xb3 putstatic Assigns a value to the static field of the specified class
0xb4 getfield Gets the instance domain of the specified class and pushes it to the top of the stack
0xb5 putfield Assigns a value to the instance field of the specified class
0xb6 invokevirtual Calling instance methods
0xb7 invokespecial Call superclass builder methods, instance initializer methods, private methods
0xb8 invokestatic Calling static methods
0xb9 invokeinterface Calling interface methods
0xba invokedynamic Calling dynamic methods
0xbb new Creates an object and pushes its reference value to the top of the stack
0xbc newarray Creates an array of the specified primitive type (such as int, float, char, etc.) and pushes its reference values to the top of the stack
0xbd anewarray Creates an array of references (such as classes, interfaces, arrays) and pushes its reference values to the top of the stack
0xbe arraylength Gets the length of the array and pushes it to the top of the stack
0xbf athrow Throws the exception at the top of the stack
0xc0 checkcast Check for type conversions, failing which throws a ClassCastException
0xc1 instanceof Checks if the object is an instance of the specified class, pushing 1 to the top of the stack, and 0 to the top otherwise
0xc2 monitorenter Gets the lock of an object that is used to synchronize a method or block
0xc3 monitorexit Release the lock of an object for synchronizing methods or blocks
0xc4 wide Expand the width of a local variable
0xc5 multianewarray Creates a multidimensional array of the specified type and the specified dimension (when executed, the stack must contain the length values for each dimension) and pushes its reference to the top of the stack
0xc6 ifnull If the value is null, it jumps
0xc7 ifnonnull The value is not null
0xc8 goto_w Unconditional jump (wide index)
0xc9 jsr_w Jumps to the specified 32-bit offset position and pushes the next instruction address of jSR_W to the top of the stack

7. Some tips

A. New DUP Invokespecial three commands are used together, which generally correspond to the new keyword in Java
B. Call a non-static class method, usually with an extra parameter, namely this, indicating that it is the current class