I heard that wechat search “Java fish” will change strong oh!

This article is posted on Github and Gitee, and contains my entire Java series of articles for study and interview purposes

(1) Overview

Many people may find JVM bytecodes mysterious, as lines of code we write can be stored as a string of hexadecimal numbers at the bottom. Down to the bottom of the computer you can execute complex code with zeros and ones. The DESIGN of the JVM is really clever, but for almost all of us developers, this is the low-level stuff that we don’t need to learn anymore, so instead of going into how the JVM bytecode is designed, we’ll go through the easiest way to quickly read the JVM bytecode.

(2) What is bytecode

The Java code we write is compiled into.class files, called bytecode files. When you open a.class, you’ll find a string of hexadecimal files starting with 0xCAFEBABE. In fact, these hexadecimal files are the key to running Java code.

These bytecodes are certainly unreadable, but there are tools to decompile bytecodes into something we can read. Java itself provides a decompiler tool called Javap.

(3) What about Java byte instruction code

3.1 Code Compilation

In order to understand Java byte instruction code, I first write a simple program:

public class Main {

    public static int calculate(a){
        int a=1;
        int b=2;
        int c=(a+b)*10;
        return c;
    }

    public static void main(String[] args) { System.out.println(calculate()); }}Copy the code

This will generate a main. class file in the target directory and then type on the command line:

javap -c Main.class
Copy the code

The instruction code comes out

public class com.javayz.test.Main {
  public com.javayz.test.Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int calculate(a);
    Code:
       0: iconst_1
       1: istore_0
       2: iconst_2
       3: istore_1
       4: iload_0
       5: iload_1
       6: iadd
       7: bipush        10
       9: imul
      10: istore_2
      11: iload_2
      12: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: invokestatic  #3                  // Method calculate:()I
       6: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
       9: return
}
Copy the code

I added an addendum at the end of the article. If you don’t use CTRL +F, you can query it directly. Here is the calculate() method.

3.2 Basic Concepts

First we need to revisit the local variator and operand stacks of the Stack in the Java Virtual machine, as well as the program counter.

In simple terms, the local variable table holds the eight basic data types, object references, and returnAddress types known to the compiler (which refer to the address of a bytecode instruction).

The operand stack is used to perform a series of operations in and out of the stack.

A program counter can be thought of as a line number indicator of the bytecode being executed by the current thread. The bytecode interpreter works by changing the value of the counter to select the next bytecode instruction to execute

3.3 Illustrated JVM instructions

Iconst means to push an int to the top of the operand stack. Iconst_1, for example, pushes the first int to the top of the operand stack

Istore means to store the top int constant in a number of variables. For example, istore_0 isto store the 1 at the top of the operand in the first variable a in the local variable table

Iload means to push the i-th local variable to the top of the stack. For example, iloAD_0 is to push the first variable to the operand stack

The first six commands are illustrated below

Iadd means to add the two elements at the top of the operand stack and push them to the top

Bipush pushes constant single-byte values (-128 to 127) to the top of the stack

Imul multiplies the top two elements and pushes them to the top of the stack

Ireturn returns the top element of the stack

The last six commands are illustrated below

From the above two figures, it should be clear how the entire byte instruction code works.

(4) Summary

The JVM instruction set has been included as an appendix at the end of this article.

No matter how complex the logic code is, it is compiled into some of the simplest commands. Sometimes it is not known whether the exclamation is too powerful in assembly language or too powerful in high-level language.

Appendix: JVM instruction set

Instruction code mnemonic description0x00The nop without operation0x01Aconst_null willnullPush to the top of the stack0x02Iconst_m1 willintType -1Push to the top of the stack0x03Iconst_0 willinttype0Push to the top of the stack0x04Iconst_1 willinttype1Push to the top of the stack0x05Iconst_2 willinttype2Push to the top of the stack0x06Iconst_3 willinttype3Push to the top of the stack0x07Iconst_4 willinttype4Push to the top of the stack0x08Iconst_5 willinttype5Push to the top of the stack0x09Lconst_0 willlongtype0Push to the top of the stack0x0aLconst_1 willlongtype1Push to the top of the stack0x0bFconst_0 willfloattype0Push to the top of the stack0x0cFconst_1 willfloattype1Push to the top of the stack0x0dFconst_2 willfloattype2Push to the top of the stack0x0eDconst_0 willdoubletype0Push to the top of the stack0x0fDconst_1 willdoubletype1Push to the top of the stack0x10Bipush takes the constant value of a single byte (-128~127) pushed to the top of the stack0x11Sipush takes a short integer constant value (-32768~32767) pushed to the top of the stack0x12LDC willint.floatOr String constant values pushed from the constant pool to the top of the stack0x13Ldc_w willint.floatOr String constant values pushed from the constant pool to the top of the stack (wide index)0x14Ldc2_w willlongordoubleType constant values are pushed from the constant pool to the top of the stack (wide index)0x15Iload will specifyintType local variable pushed to the top of the stack0x16Lload will be specifiedlongType local variable pushed to the top of the stack0x17Fload will be specifiedfloatType local variable pushed to the top of the stack0x18Dload will specifydoubleType local variable pushed to the top of the stack0x19Aload pushes the specified reference type local variable to the top of the stack0x1aIload_0 will be the first oneintType local variable pushed to the top of the stack0x1bIload_1 will be the secondintType local variable pushed to the top of the stack0x1cIload_2 will be the thirdintType local variable pushed to the top of the stack0x1dIload_3 will be the fourthintType local variable pushed to the top of the stack0x1eLload_0 will be the firstlongType local variable pushed to the top of the stack0x1fLload_1 will be the secondlongType local variable pushed to the top of the stack0x20Lload_2 will be the thirdlongType local variable pushed to the top of the stack0x21Lload_3 will be the fourthlongType local variable pushed to the top of the stack0x22Fload_0 will be the firstfloatType local variable pushed to the top of the stack0x23Fload_1 will be the secondfloatType local variable pushed to the top of the stack0x24Fload_2 will be the thirdfloatType local variable pushed to the top of the stack0x25Fload_3 will be the fourthfloatType local variable pushed to the top of the stack0x26Dload_0 will be the firstdoubleType local variable pushed to the top of the stack0x27Dload_1 will be the seconddoubleType local variable pushed to the top of the stack0x28Dload_2 will be the thirddoubleType local variable pushed to the top of the stack0x29Dload_3 will be the fourthdoubleType local variable pushed to the top of the stack0x2aAload_0 pushes the first reference type local variable to the top of the stack0x2bAload_1 pushes the second reference type local variable to the top of the stack0x2cAload_2 pushes the third reference type local variable to the top of the stack0x2dAload_3 pushes the fourth reference type local variable to the top of the stack0x2eIaload willintType specifies that the index value is pushed to the top of the stack0x2fLaload willlongType specifies that the index value is pushed to the top of the stack0x30Faload willfloatType specifies that the index value is pushed to the top of the stack0x31Daload willdoubleType specifies that the index value is pushed to the top of the stack0x32Aaload pushes the value of the specified index of the reference array to the top of the stack0x33Baload willbooleanorbyteType specifies that the index value is pushed to the top of the stack0x34Caload willcharType specifies that the index value is pushed to the top of the stack0x35Saload willshortType specifies that the index value is pushed to the top of the stack0x36Istore will stackintThe value of type is stored in the specified local variable0x37Lstore will stacklongThe value of type is stored in the specified local variable0x38Fstore will stackfloatThe value of type is stored in the specified local variable0x39Dstore will stackdoubleThe value of type is stored in the specified local variable0x3aAstore stores the top of the stack reference value into the specified local variable0x3bIstore_0 will stackintType is stored in the first local variable0x3cIstore_1 will stackintThe value of type is stored in the second local variable0x3dIstore_2 will stackintThe value of type is stored in a third local variable0x3eIstore_3 will stackintThe value of type is stored in the fourth local variable0x3fLstore_0 will stacklongType is stored in the first local variable0x40Lstore_1 will stacklongThe value of type is stored in the second local variable0x41Lstore_2 will stacklongThe value of type is stored in a third local variable0x42Lstore_3 will stacklongThe value of type is stored in the fourth local variable0x43Fstore_0 will stackfloatType is stored in the first local variable0x44Fstore_1 will stackfloatThe value of type is stored in the second local variable0x45Fstore_2 will stackfloatThe value of type is stored in a third local variable0x46Fstore_3 will stackfloatThe value of type is stored in the fourth local variable0x47Dstore_0 will stackdoubleType is stored in the first local variable0x48Dstore_1 will stackdoubleThe value of type is stored in the second local variable0x49Dstore_2 will stackdoubleThe value of type is stored in a third local variable0x4aDstore_3 will stackdoubleThe value of type is stored in the fourth local variable0x4bAstore_0 stores the top of the stack reference value into the first local variable0x4cAstore_1 stores the top of the stack reference value into the second local variable0x4dAstore_2 stores the top of the stack reference value into the third local variable0x4eAstore_3 stores the top of the stack reference value into the fourth local variable0x4fIastore will stackintType is stored at the specified index position of the specified array0x50Lastore will stacklongType is stored at the specified index position of the specified array0x51Fastore will stackfloatType is stored at the specified index position of the specified array0x52Dastore will stackdoubleType is stored at the specified index position of the specified array0x53Aastore stores the top of the stack reference value at the specified index position of the specified array0x54Bastore will stackbooleanorbyteType is stored at the specified index position of the specified array0x55Castore will stackcharType is stored at the specified index position of the specified array0x56Sastore will stackshortType is stored at the specified index position of the specified array0x57Pop pops the top value of the stack (value cannot belongordoubleTypes of)0x58Pop2 sets the top (longordoubleType) or two values pop up (other)0x59Dup copies the top value of the stack and pushes the copied value to the top0x5aDup_x1 copies the top value of the stack and pushes the two copies to the top0x5bDup_x2 copies the top value of the stack and pushes three (or two) copies to the top0x5cDup2 replication stack top (longordoubleType) or two (other) values and pushes the copy value to the top of the stack0x5dDup2_x1 copies one or two values from the top of the stack and inserts them below the two or three values from the top of the stack0x5eDup2_x2 copies one or two values at the top of the stack and inserts them below the two, three, or four values at the top0x5fSwap swaps the top two values of the stack (values cannot belongordoubleTypes of)0x60Iadd will top the stack by twointType values are added and pushed to the top of the stack0x61Ladd will top the stack by twolongType values are added and pushed to the top of the stack0x62Fadd will top the stack by twofloatType values are added and pushed to the top of the stack0x63Dadd will top the stack by twodoubleType values are added and pushed to the top of the stack0x64Isub will be the top two on the stackintType and push the result to the top of the stack0x65Lsub will be the top two on the stacklongType and push the result to the top of the stack0x66Fsub will stack the top twofloatType and push the result to the top of the stack0x67Dsub will stack the top twodoubleType and push the result to the top of the stack0x68Imul will stack top twointType and push the result to the top of the stack0x69Lmul will be the top two on the stacklongType and push the result to the top of the stack0x6aFmul will stack the top twofloatType and push the result to the top of the stack0x6bDmul will stack the top twodoubleType and push the result to the top of the stack0x6cIdiv will stack the top twointType and push the result to the top of the stack0x6dLdiv will top the stack by twolongType and push the result to the top of the stack0x6eFdiv will be the top two on the stackfloatType and push the result to the top of the stack0x6fDdiv will top the stack by twodoubleType and push the result to the top of the stack0x70Irem is going to be the top two on the stackintType and push the result to the top of the stack0x71Lrem is going to be the top two on the stacklongType and push the result to the top of the stack0x72Frem will stack the top twofloatType and push the result to the top of the stack0x73Drem will stack the top twodoubleType and push the result to the top of the stack0x74Ineg will stackintType takes a negative value and pushes the result to the top of the stack0x75Lneg will stacklongType takes a negative value and pushes the result to the top of the stack0x76Fneg will stackfloatType takes a negative value and pushes the result to the top of the stack0x77Dneg will stackdoubleType takes a negative value and pushes the result to the top of the stack0x78Ishl willintType shifts the specified number of bits left and pushes the result to the top of the stack0x79LSHL willlongType shifts the specified number of bits left and pushes the result to the top of the stack0x7aIshr willintType shifts the value of the specified digit right (symbol) and pushes the result to the top of the stack0x7bLSHR willlongType shifts the value of the specified digit right (symbol) and pushes the result to the top of the stack0x7cIushr willintThe value of type (unsigned) shifts the specified number of digits and pushes the result to the top of the stack0x7dLushr willlongThe value of type (unsigned) shifts the specified number of digits and pushes the result to the top of the stack0x7eIand is going to be the top two on the stackintType values are bitwise and pushed to the top of the stack0x7fLand will be the top two on the stacklongType values are bitwise and pushed to the top of the stack0x80The IOR will be the top two on the stackintType and push the result to the top of the stack0x81Lor is going to stack the top twolongType and push the result to the top of the stack0x82Ixor is going to be the top two on the stackintType values are bitwise xor and pushed to the top of the stack0x83Lxor will be the top two on the stacklongType values are bitwise xor and pushed to the top of the stack0x84Iinc will specifyintType variable increments the specified value (I ++, I --, I +=)2)0x85I2l will stackintType is cast tolongType and push the result to the top of the stack0x86I2f will stackintType is cast tofloatType and push the result to the top of the stack0x87I2d will stackintType is cast todoubleType and push the result to the top of the stack0x88L2i will stacklongType is cast tointType and push the result to the top of the stack0x89L2f will stacklongType is cast tofloatType and push the result to the top of the stack0x8aL2d will stacklongType is cast todoubleType and push the result to the top of the stack0x8bF2i will stackfloatType is cast tointType and push the result to the top of the stack0x8cF2l will stackfloatType is cast tolongType and push the result to the top of the stack0x8dF2d will stackfloatType is cast todoubleType and push the result to the top of the stack0x8eD2i will stackdoubleType is cast tointType and push the result to the top of the stack0x8fD2l will stackdoubleType is cast tolongType and push the result to the top of the stack0x90D2f will stackdoubleType is cast tofloatType and push the result to the top of the stack0x91I2b will stackintType is cast tobyteType and push the result to the top of the stack0x92I2c will stackintType is cast tocharType and push the result to the top of the stack0x93I2s will stackintType is cast toshortType and push the result to the top of the stack0x94LCMP compares the top two on the stacklong, and the result (1.0, -1) to the top of the stack0x95FCMPL compares the top two on the stackfloat, and the result (1.0, -1) push to the top of the stack; When one of the values is NaN, will -1Pressure into the stack0x96FCMPG compares the top two on the stackfloat, and the result (1.0, -1) push to the top of the stack; When one of the values is NaN, will1Pressure into the stack0x97DCMPL compares the top two on the stackdouble, and the result (1.0, -1) push to the top of the stack; When one of the values is NaN, will -1Pressure into the stack0x98DCMPG compares the top two on the stackdouble, and the result (1.0, -1) push to the top of the stack; When one of the values is NaN, will1Pressure into the stack0x99Ifeq when stackintThe value of the0When to jump0x9aIfne when stackintThe value of type is not equal to0When to jump0x9bIflt when stackintIs less than0When to jump0x9cIfge when stackintType is greater than or equal to0When to jump0x9dIfgt when stackintIs greater than0When to jump0x9eIfle when stackintType is less than or equal to0When to jump0x9fIf_icmpeq compares the top two stacksintType numerical size when the result is equal to0When to jump0xa0If_icmpne compares the top two on the stackintType numerical size when the result is not equal to0When to jump0xa1If_icmplt compares the top two on the stackintType numerical size when the result is less than0When to jump0xa2If_icmpge compares the top two on the stackintType when the result is greater than or equal to0When to jump0xa3If_icmpgt compares the top two on the stackintType numerical size when the result is greater than0When to jump0xa4If_icmple compares the top two stacksintType when the result is less than or equal to0When to jump0xa5If_acmpeq compares two referential values at the top of the stack and jumps if the results are equal0xa6If_acmpne compares two referential values at the top of the stack and jumps if the results are not equal0xa7Goto Unconditional jump0xa8JSR jumps to the specified16Offset position and push the address of the next JSR instruction to the top of the stack0xa9Ret returns the instruction location of the index specified by the local variable (usually used in conjunction with JSR, jSR_w)0xaaTableswitch forswitchConditional jump,caseValue continuous (variable length instruction)0xabLookupswitch forswitchConditional jump,caseValue discontinuity (variable length instruction)0xacIreturn returns from the current methodint
0xadLreturn returns from the current methodlong
0xaeFreturn returns from the current methodfloat
0xafDreturn returns from the current methoddouble
0xb0Areturn returns an object reference from the current method0xb1 returnReturns from the current methodvoid
0xb2Getstatic gets the static field of the specified class and pushes its value to the top of the stack0xb3Putstatic assigns a value to the static field of the specified class0xb4Getfield gets the instance field of the specified class and pushes its value to the top of the stack0xb5Putfield assigns a value to the instance field of the specified class0xb6Invokevirtual calls the instance method0xb7Invokespecial calls the superclass constructor, instance initialization method, and private method0xb8Invokestatic invokes static methods0xb9Invokeinterface invokes the interface method0xbaInvokedynamic invokes dynamic linking methods0xbb newCreates an object and pushes its reference to the top of the stack0xbcNewarray creates a specified primitive type (e.gint.float.char...). And push its reference values to the top of the stack0xbdAnewarray creates an array of references (such as classes, interfaces, arrays) and pushes its reference values to the top of the stack0xbeArraylength gets the length of the array and pushes it to the top of the stack0xbfAthrow throws the exception at the top of the stack0xc0Checkcast checks type conversions and a ClassCastException is thrown if the check fails0xc1 instanceofChecks whether the object is an instance of the specified class, if it is1Push to the top of the stack, otherwise0Pressure into the stack0xc2Monitorenter acquires locks on objects that it uses to synchronize methods or blocks0xc3Monitorexit releases locks on objects for synchronizing methods or blocks0xc4Wide Enlarges the width of the local variable index0xc5Multianewarray creates a multidimensional array of the specified type and dimension (when executed, the stack must contain the length values for each dimension) and pushes its reference values to the top of the stack0xc6Ifnull fornullWhen to jump0xc7Ifnonnull not fornullWhen to jump0xc8Goto_w Indicates an unconditional forward0xc9Jsr_w Jumps to the specified32Offset position and press jsr_w the next instruction address into the stack = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =0xcaBreakpoint marks for breakpoints during debugging0xfeImpdep1 language backdoor reserved for specific software0xffImpdep2 language backdoors reserved for specific hardware the last three are reserved instructionsCopy the code