java高分局之jvm指令浅析
几个简单的指令
- iconst:是把常量池中的值加载到操作数栈,比如:iconst_1把第一个常量加载到操作数栈。
- ipush:这个指令和iconst_的功能相同,是指把常量n加载到操作数栈,n是作为参数传给ipush指令,n代表具体的常量值。
- iload:把局部变量表中第n个变量加载到操作数栈。
- istore:把操作数栈顶元素存入第n个局部变量。
- iadd:把操作数栈顶两个元素相加,然后把结果重新存入栈顶。
操作数栈、常量池和局部变量表
一段小程序
public class Test {
public static void main(String[] args) {
int i=0;
int j=1;
int n = i + j;
}
}
字节码如下
分步解析字节码
上面的程序有编译后常量池中会存在两个值:0和1。局部变量表中会存在3个变量分别是:I,j和f,如下图所示:
编译后成为9行字节码指令,我们下面一步一步的看一下这个执行过程:
iconst_0:表示把第0个常量加载到操作数栈,可见常量池的下标是从0开始的。如下图所示:
istore_1:表示把操作数栈顶的元素存储到第一个局部变量表中,删除栈顶元素。局部变量表的下标是从1开始的?这是错误的,在这里因为main方法有参数,所以参数是局部变量表的第一个元素。所以局部变量表的下标也是从0开始的,局部变量表。如下图所示:
iconst_1:把下标为1的常量值加载到栈顶,如下图所示:
istore_2:把操作数栈顶元素存储到第二个局部变量,删除栈顶元素。如下图所示:
iload_1:加载第一个局部变量到栈顶,如下图所示:
iload_2:加载第二个局部变量到栈顶,其他栈中元素下移,如下图:
iadd:把栈顶的两个元素相加,然后删除栈顶两个元素,再把相加的结果压入栈顶,如下图所示:
istore_3:把栈顶元素存入第3个局部变量表中,如下图所示:
return:方法返回