天天看点

浅谈虚拟机(2.2)如何捅出了这一刀の操作数栈操作数栈

操作数栈

重点知识:

  • 操作数:待操作的数据
  • 操作码:操作指令本身
  • PC(程序计数器):一个寄存器,存放操作的首地址
  • 操作:由多条指令形成一个操作

操作数栈也是存放在栈帧中的一块内存区域,仅存放两种数据:操作数、操作码。在JVM中,用到的寄存器只有PC(程序计数器)寄存器,因此指令的存放需要一块内存区域,这个区域就是操作数栈了。

我们通过一段很简单的代码来看,操作数栈是怎样工作的。

public class Main{
    public static void main(String[] args){
        int i = ;
        int j = ;      
        i = i + j;
        return;
    }
}
           

用javap -verbose 在命令行反编译该代码,结果如下

浅谈虚拟机(2.2)如何捅出了这一刀の操作数栈操作数栈

从代码里面我们可以看到应该有三条操作,分别是对两个变量的赋值和一条i + j的操作。在此再对反编译的结果进行解读。以下为顺序解释

  1. 将int型常量1入栈到操作数栈。(普及一下,jvm的iconst指令用于将-1~5的int型常量入栈,其中-1用iconst_m1入栈)
  2. 将栈顶数据出栈到局部变量索引为1的内存单元(局部变量表索引从0开始)
  3. 将int型常量2入栈
  4. 出栈并存入局部变量索引为2的内存单元
  5. 将局部变量表第一个数据入栈
  6. 将局部变量表第二个数据入栈
  7. 将栈顶两个数据相加,并将结果压入栈顶
  8. 将相加返回的结果存入局部变量表第一个内存单元(变量i)
  9. 方法返回

下面看一下内存的演示图!

浅谈虚拟机(2.2)如何捅出了这一刀の操作数栈操作数栈

我们可以看到,反编译出来的内容入栈和出栈都是操作数栈。而局部变量表尽管在虚拟机栈中,却不是栈式存储,而是随机存取方式,根据索引进行存取。

回顾:操作数栈存储的是操作的信息,操作数和操作码。与局部变量表做一个对比,局部变量表中存放的是很单纯的局部变量,其数据操作需要与操作数栈进行交互,才能将其变为准备被操作的数据。