java - 怎么理解JVM中的iload和istore指令
问题描述
我最近在学习JVM,被istore和iload两条指令困扰了。以下是我查看《Java虚拟机规范》得到的解释
将一个局部变量加载到操纵栈的指令包括:iload、iload_、lload…
将一个数值从操作数栈存储到局部变量表的指令包括:istore、istore_、lstore…
下面是我的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到操作数栈上。不知道,是不是我哪步理解错了,谢谢指点。
问题解答
回答1:如果把代码换成
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,那么也不会多出来第五步和第六步。
回答2:楼上正解,其实结合代码看下就可以很明白的看出原因了。
首先这个方法是静态方法,所以局部变量数组【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 //返回栈顶元素回答3:
一个小错误,局部变量表的index是从0开始的。
编译器生成的字节码完全是按照方法中的语义生成的,没有太多优化。
iadd指令对应的a+b中加法操作,下一步的istore_2对应的就是c=的赋值操作,也就是保存到局部变量表,后面的iload_2对应的就是return中取c的值。
相关文章:
1. java - Spring boot启动时报错?2. 用Java写发送邮件的程序,经常被当做垃圾邮件处理怎么解决3. java - 当在子类中声明一个父类中存在的变量后,自动调用的父类构造函数不起作用。4. angular.js - angular2 基础问题,求解答5. angular.js - angular双向绑定机制异常6. angular.js - 有没有不需要先git clone xxxx的angular2的教程?7. angular.js - 报这个错是什么原因呢?没有显示,因为报错,可是controller里没有这个错8. angular.js - 求Angular ui-router 多层嵌套的Demo!9. angular.js - angularjs 如何用一组按钮完成单选10. android - recyclerview显示错乱