搜尋

首頁  >  問答  >  主體

java - 怎么理解JVM中的iload和istore指令

我最近在学习JVM,被istore和iload两条指令困扰了。
以下是我查看《Java虚拟机规范》得到的解释

下面是我的java代码

    public static int add(int a,int b){
        int c=0;
        c=a+b;
        return c;
    }

下面是编译后的字节码,也加上了我的理解,如果解释不恰当,谢谢指出

0: iconst_0        //常量0压入操作数栈
1: istore_2        //弹出操作数栈栈顶元素,保存到局部变量表第2个位置
2: iload_0         //第0个变量压入操作数栈
3: iload_1         //第1个变量压入操作数栈
4: iadd            //操作数栈中的前两个int相加,并将结果压入操作数栈顶
5: istore_2        //弹出操作数栈栈顶元素,保存到局部变量表第2个位置
6: iload_2         //加载局部变量表的第2个变量到操作数栈顶
7: ireturn         //返回

从上面字节码的分析看,指令4已经将计算结果压入到操作数栈了,而指令6又是把结果压入到操作数栈,这不是重复工作吗。
如果存入操作数栈的意义是为了可以store到局部变量表中,那第6步又为什么要load到操作数栈上。
不知道,是不是我哪步理解错了,谢谢指点。

PHPzPHPz2787 天前1323

全部回覆(3)我來回復

  • PHP中文网

    PHP中文网2017-04-18 10:51:52

    如果把程式碼換成

    public static int add(int a,int b){
            int c=0;
            return a+b;
        }

    那麼指令對應就是:

           0: iconst_0
           1: istore_2
           2: iload_0
           3: iload_1
           4: iadd
           5: ireturn

    編譯器就是按照程式碼來產生的,如果直接 return a + b,那麼就不會多出來第五步和第六步。

    回覆
    0
  • 黄舟

    黄舟2017-04-18 10:51:52

    樓上正解,其實結合程式碼看下就可以很明白的看出原因了。

    首先這個方法是靜態方法,所以局部變數數組【0】【1】【2】對應的變數分別為a、b、c;

    0: iconst_0        //常量0入栈
    1: istore_2        //将栈顶出栈,即c=0;
    2: iload_0         //复制a变量的值入栈
    3: iload_1         //复制b变量的值入栈
    4: iadd            //将栈顶两个元素出栈,做加法,然后把结果再入栈(即a,b出栈,将a+b入栈)
    5: istore_2        //栈顶元素出栈,即c=和;  此时栈为空
    6: iload_2         //将c赋值压入栈
    7: ireturn         //返回栈顶元素
    
    

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:52

    一個小錯誤,局部變數表的index是從0開始的。

    編譯器產生的字節碼完全是按照方法中的語意產生的,沒有太多最佳化。

    iadd指令对应的a+b中加法操作,下一步的istore_2对应的就是c=的赋值操作,也就是保存到局部变量表,后面的iload_2对应的就是return中取c的值。

    回覆
    0
  • 取消回覆