JVM字节码之整型iconst、istore、iload指令

局部变量表

       局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数和方法内定义的局部变量。

       一个局部变量可以保存一个类型为boolean、byte、char、short、int、float、reference和returnAddress类型的数据。reference类型表示对一个对象实例的引用。

第1个位置问题

非静态函数

在这里插入图片描述
从istore_1开始

istore_0 = this

静态函数

在这里插入图片描述
从istore_0开始

操作数栈

操作数栈(Operand Stack)也常称为操作栈,它是一个后入先出栈(LIFO)。同局部变量表一样,操作数栈的最大深度也在编译的时候写入到方法的Code属性的max_stacks数据项中
当一个方法刚刚开始执行时,其操作数栈是空的,随着方法执行和字节码指令的执行,会从局部变量表或对象实例的字段中复制常量或变量写入到操作数栈,再随着计算的进行将栈中元素出栈到局部变量表或者返回给方法调用者,也就是出栈/入栈操作。一个完整的方法执行期间往往包含多个这样出栈/入栈的过程。

iconst

当int取值 -128~127 时,JVM采用 bipush 指令将常量压入栈中

-1至5

当int取值-1~5时,JVM采用iconst指令将常量压入栈中
int 取值 0~5 时,JVM采用 iconst_0、iconst_1、iconst_2、iconst_3、iconst_4、iconst_5指令将常量压入栈中;
取值-1时,采用iconst_m1指令将常量压入栈中

public int getInt1(){
        int af1 = -1;  // iconst_m1
        int a0 = 0;    // iconst_0
        int a1 = 1;
        int a2 = 2;
        int a3 = 3;
        int a4 = 4;
        int a5 = 5;

        return 10;
    }

在这里插入图片描述

add 例子1

   public int add(){
        int a = -1;
        int b = 3;
        return a+b;
    }
 public int add();
    Code:
       0: iconst_m1   //常量-1加载到操作数栈
       1: istore_1     // 将-1从操作数栈存储到局部变量表 第2个位置
       2: iconst_3    //常量3加载到操作数栈
       3: istore_2     // 将常量3从操作数栈存储到局部变量表 第3个位置
       4: iload_1     // 加载局部变量第1个变量压入操作数栈
       5: iload_2     // 加载局部变量第2个变量压入操作数栈
       6: iadd         // 操作数栈中的前两个变量相加,并将结果压入操作数栈顶
       7: ireturn     // 返回

add 例子2

public int add1(){
        int a = 5;
        int b = 6;
        return a+b;
    }
public int add1();
    Code:
       0: iconst_5              // 常量5加载到操作数栈
       1: istore_1              // 将5从操作数栈存储到局部变量表 第2个位置
       2: bipush        6      // 常量6加载到操作数栈
       4: istore_2             // 将6从操作数栈存储到局部变量表 第3个位置
       5: iload_1              // 加载局部变量第1个变量压入操作数栈
       6: iload_2              // 加载局部变量第1个变量压入操作数栈
       7: iadd                  // 操作数栈中的前两个变量相加,并将结果压入操作数栈顶
       8: ireturn              // 返回

iload

非静态方法

从iload_1开始的,默认第iload_0是this

在这里插入图片描述

    public int getSize1(int a,int b){
    
    
       int result = a +b+ 10;
       return result;

    }

 public int getSize1(int, int);
    descriptor: (II)I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=3
         0: iload_1              // 从iload_1开始  iload_0是this
         1: iload_2
         2: iadd
         3: bipush        10
         5: iadd
         6: istore_3       //0:this 1:a 2:b  3:result
         7: iload_3
         8: ireturn

静态方法

从iload_0开始的

在这里插入图片描述

public static int getStaticSize(int a,int b){
    
    
   int result = a +b+ 10;
   return result;
}

public static int getStaticSize(int, int);
    descriptor: (II)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=2
         0: iload_0       // 从iload_0开始
         1: iload_1
         2: iadd
         3: bipush        10
         5: iadd
         6: istore_2    //0:a 1:b  2:result
         7: iload_2
         8: ireturn

多种类型demo

在这里插入图片描述
在这里插入图片描述

  int size = 20;
  int MAX = 100;
 public int add(int a){
    
    
        int result = a +size+ 10 + MAX;
        return result;

  }

public int add(int);
    descriptor: (I)I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=2
         0: iload_1              // 从局部变量第1个位置加载到操作数栈顶
         1: aload_0             //  把 this 装载到操作数栈顶 
         2: getfield      #3   // Field size:I  将栈顶的指定的对象的第 4 个实例域(Field)的值,压入栈顶。#3 就是指的我们的成员变量size
         5: iadd              // a+this.size  并将结果压入操作数栈顶
         6: bipush        10  // 将常量10压入操作数栈顶
         8: iadd             // 上1个iadd的结果集和10相加 并将结果压入操作数栈顶
         9: aload_0          // 把 this 装载到操作数栈顶 
        10: getfield      #5      // Field MAX:I   将栈顶的指定的对象的第 6 个实例域(Field)的值,压入栈顶。#5 就是指的我们的成员变量MAX
        13: iadd           // 上1个iadd的结果集和this.MAX相加 并将结果压入操作数栈顶
        14: istore_2       // 把result放到具备变量的第3个位置
        15: iload_2        // 从局部变量第3个位置的值  压入操作数栈顶
        16: ireturn        // 返回

猜你喜欢

转载自blog.csdn.net/kq1983/article/details/113406715