10.加载与存储指令(load、const、push、lcd、store系列)

1.加载与存储指令概述

  1. 作用:加载与存储指令用于将数据从栈帧的局部变量和操作数栈之间来回传递。
  2. 将一个局部变量加载到操作数栈:xloadxload_<n>,其中<n>0-3
  3. 将一个常量加载到操作数栈:bipushsipushldciconst_<n>等,其中<n>0-3
  4. 将一个数值从操作数栈存储到局部变量表:xstorexstore_<n>
    在这里插入图片描述

1.1.操作数栈和局部变量表复习

1.1.1 操作数栈

详细介绍可以参考另一篇博客:https://blog.csdn.net/u011069294/article/details/107106755
1.操作数栈位于栈帧中,用于存放计算的操作数和返回结果。执行每一条指令之前,操作数会被压入到操作数栈中;在执行指令时,从操作数栈中弹出所需的操作数,并且将指令的结果重新压入栈中。
例如:图中所示的计算1+2的例子,使用的是iadd指令,操作数栈顶的两个元素分别是12iadd指令将弹出这两个数,并且将求得的结果3压入栈中。
在这里插入图片描述

1.1.2 局部变量表

详细介绍可以参考另一篇博客:https://blog.csdn.net/u011069294/article/details/107067408

  1. 局部变量表是栈帧中另一个重要的组成部分。存放的是this(非静态方法)、方法传入的参数、以及方法的局部变量。
    在这里插入图片描述
  2. longdouble类型的变量占两个变量槽(slot),共8个字节,其他的变量类型都只占一个solt。一个solt4个字节。
    在这里插入图片描述
    例子:如下图所示一个绿色的方格代表一个solt,对于foo方法的栈帧的局部变量表中存储的依次是this变量、l(占两个solt)变量、f变量、i变量s变量(存在solt复用的情况,由于i出了大括号作用域就没用了,所以后面的s变量可以复用i变量的solt
  3. 需要注意的一点是,在栈帧中,与性能调优相关的部分就是局部变量表。因为局部变量表中的变量是重要的垃圾回收根节点,只要被局部变量表中的数据直接或间接引用的的对象都不能被回收。
    在这里插入图片描述

1.2 局部变量压栈指令(load指令系列)

  1. 局部变量压栈指令将局部变量表中的数据压入到操作数栈中。
  2. 大体上可以分为xload_<n>xload两类。其中x表示的是数据类型,<n>表示的是将局部变量表中角标为n的局部变量压入操作数栈,n的取值范围为0-3,当局部变量超过了3个的时候,就需要使用xload
    在这里插入图片描述
    例子:需要注意的是局部变量表中存储的是局部变量的值。只不过为了方便,这里图中写的变量的名字。
    在这里插入图片描述

1.3 常量入栈指令(constpushldc系列)

  1. 作用:将常量压入操作数栈中。分为const系列、push系列和ldc指令。
  2. 指令const系列:用于对特定的常量入栈,入栈的常量隐藏在指令本身里。例如:iconst_<i>(i-15),用于将int类型的-15压入栈中。aconst_null这条指令,a表示的引用类型,null是压入栈的值。
    可以发现,const系列能够操作的数据都有一个范围,如果需要操作这个范围以外的数据怎么办?例如,iconst操作的范围是-15,如果需要将6压入操作数栈中怎么办?
  3. 为了解决上面的问题,有了push系列的指令。push指令分为bipushsipush,分别表示的是将一个字节(b表示byte )的整数和两个字节(s表示short)的整数压入到操作数栈中。
    可以发现,一个字节和两个字节,能够操作的数的范围也有限,超过这个范围怎么办?
  4. 最终,为了解决上面的问题,又引入万能的ldc指令。接收一个8位的参数,该参数指向常量池中的intfloat或者String类型的索引,将字符串常量池中对应的内容压入栈中。
    在这里插入图片描述
  5. 各个指令能够操作的数的范围如下表所示:
    在这里插入图片描述
    例子: 代码和对应的常量入栈指令对应关系,如下图所示。可以发现,当超过iconst能够操作的范围的时候,使用的是bipush,超过bipush能够操作的范围之后,使用sipush,超过sipush能够操作的范围之后,使用的是ldc
    同理对于其他数据类型的常量入栈指令也是类似的。
    在这里插入图片描述

1.4 出栈装入局部变量表指令(store系列)

  1. 作用:将操作数栈中的栈顶元素弹出,装入局部变量表的指定位置,给局部变量赋值。
  2. 分为xstorexstore_n两种。其中x表示的是数据类型,n表示的是局部变量表索引位置。xstore需要带一个byte类型的参数,指明局部变量表索引位置。
    在这里插入图片描述
    例子:
    在这里插入图片描述

总结

可以发现,除了store是从栈中取数据放到局部变量表中。其它的命令都是从局部变量表中取数据压入栈中。

更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值