JVM 字节码 (一) 加载和存储指令

本文主要讲load,store,const,push等字节码的实例即应用。

声明局部变量并赋值

源程序

                int x = 2;
                int y = 3;

字节码

0 iconst_2 将常量(2)压入操作数栈中
1 istore_1 将操作栈的值弹出,即常量(2)并赋值给第1个局部变量x
2 iconst_3 将常量(3)压入操作数栈中
3 istore_2 弹出当前操作数栈中的第一个值,即(3),并赋值给第二个局部变量,即y
4 return

先声明局部变量,再赋值

程序

    int i, j;
    j = 200;
    i = 100;

字节码

0 sipush 200  将Short型数字常量(200)加载到操作数栈中
3 istore_2 弹出当前操作数栈中的第一个值(200),并赋值给第二个局部变量(j)
4 bipush 100 将Byte型常量(100)加载到操作数栈中
6 istore_1 弹出当前操作数栈中的第一个值(100), 并赋值给第一个局部变量(i)
7 return

分析

(1)对于局部变量的声明顺序将会导致存在局部变量表中的顺序
(2)对于一步的赋值操作,会先把常量加载到操作数栈中并赋值
(3)istore_<i>,i即表示局部变量的下标,从0开始,因为实例程序是main方法,所以args是下标为0的局部变量
(4)先声明后赋值,对于常量如100,1这种数字,会根据实际的常量的值来进行设置值的类型,二如果是直接int x = 1 ,那么1的存储方式就是一个Integer
(5)bipush/sipush这种push方式,会直接获取它的直接操作数,即后面的100,并压入操作数栈中

Tip: 当int取值-1~5采用iconst指令,取值-128~127采用bipush指令,取值-32768~32767采用sipush指令,取值-2147483648~2147483647采用 ldc 指令。

先声明局部变量,再赋值为局部变量

程序

int i, j;
j = 200;
i = j;

字节码

0 sipush 200 压常量入栈
3 istore_2 弹出并赋值局部变量_2
4 iload_2 加载局部变量_2入栈
5 istore_1 弹出并赋值局部变量_1 即 i = j的语义实现
6 return

分析

(1)对于局部变量的相互赋值会在复制前把值对应的变量加载到栈中,使用iload指令

先声明局部变量,再连续赋值

程序

int i, j, k;
j = 200;
k = i = j;

字节码

0 sipush 200 压常量入栈
3 istore_2 弹出并赋值局部变量_2
4 iload_2 加载局部变量_2入栈
5 dup 复制栈顶,相当于iload_2执行了两次
6 istore_1 赋值给局部变量_1
7 istore_3 赋值给局部变量_3
8 return

分析

由上可知,
(1)对于连等于号,使用dup指令
(2)离值越近的越早赋值

猜你喜欢

转载自blog.csdn.net/u013076044/article/details/79339270