欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于栈的指令集与基于寄存器的指令集的区别

程序员文章站 2022-06-08 22:59:42
...

文章目录

  • 一、两种指令集的区别
  • 二、代码直观演示两种指令集架构
  • 三、基于栈的解释器执行过程

一、两种指令集的区别

指令集的架构模型分为基于栈的指令集架构基于寄存器的指令集架构两种,HotSpot虚拟机中的任何操作都需要入栈和出栈的步骤,即使用栈来管理运行,而HotSpot本身就是基于栈的指令集架构
基于寄存器架构的指令集典型应用是传统PC上x86的二进制指令集、Android的Davlik虚拟机(Google在Android上就选择了此种方案)。

下图展示了两种指令集架构的区别:基于栈的指令集与基于寄存器的指令集的区别

二、代码直观演示两种指令集架构

下面举个例子,分别使用这两种指令集计算2+3的结果

在IDEA中对2+3操作进行javap -v反编译,得到了8行指令集。这里只需要要和基于寄存器得出的指令集做一个直观的对比即可,更详细的执行栈式执行过程可以参照下文给出的另一个例子。
基于栈的指令集与基于寄存器的指令集的区别

而使用寄存器架构对2+3操作的指令集只有下面两行

基于栈的指令集与基于寄存器的指令集的区别

三、基于栈的解释器执行过程

下面通过一段Java代码,演示虚拟机中的字节码是如何执行的
基于栈的指令集与基于寄存器的指令集的区别

stack=2,locals=4
可以看到Javap提示这段代码需要深度为2的操作数栈和4个变量操的局部变量空间。

基于栈的指令集与基于寄存器的指令集的区别

bipush指令的作用是将单字节的整形常量值(-128~127)推入操作数栈顶端,跟随有一个参数,指明推送的常量值是多少,这里是100。

基于栈的指令集与基于寄存器的指令集的区别

istore_1指令的作用是将操作数栈顶的整型值出栈并存放到第1个局部变量槽中。 后续4条指令(直到偏移为11的指令为止) 都是做一样的事情, 也就是在对应代码中把变量
a、 b、 c赋值为100、 200、 300。 这4条指令的图示略过。
基于栈的指令集与基于寄存器的指令集的区别
iload_1指令的作用是将局部变量表第1个变量槽中的整型值复制到操作数栈顶端。
基于栈的指令集与基于寄存器的指令集的区别

iload_2指令的执行过程与iload_1类似, 把第2个变量槽的整型值入栈。

基于栈的指令集与基于寄存器的指令集的区别

iadd指令的作用是将操作数栈中头两个栈顶元素出栈, 做整型加法,然后把结果重新入栈。 在iadd指令执行完毕后, 栈中原有的100和200被出栈,它们的和300被重新入栈。

基于栈的指令集与基于寄存器的指令集的区别

iload_3指令把存放在第3个局部变量槽中的300入栈到操作数栈中。 这时操作数栈为两个整数300。 下一条指令imul是将操作数栈中头两个栈顶元素出栈, 做整型乘法, 然后
把结果重新入栈, 与iadd完全类似, 故省略图示。

基于栈的指令集与基于寄存器的指令集的区别

ireturn指令是方法返回指令之一, 它将结束方法执行并将操作数栈顶的整型值返回给该方法的调用者。 到此为止, 这段方法执行结束。

相关标签: Java JVM