基于栈的指令集与基于寄存器的指令集的区别
文章目录
- 一、两种指令集的区别
- 二、代码直观演示两种指令集架构
- 三、基于栈的解释器执行过程
一、两种指令集的区别
指令集的架构模型分为基于栈的指令集架构
与基于寄存器的指令集架构
两种,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指令是方法返回指令之一, 它将结束方法执行并将操作数栈顶的整型值返回给该方法的调用者。 到此为止, 这段方法执行结束。
上一篇: ARM 嵌入式微处理器指令集(下)
推荐阅读
-
基于Python __dict__与dir()的区别详解
-
基于session_unset与session_destroy的区别详解
-
PHP中基于ts与nts版本- vc6和vc9编译版本的区别详解
-
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
-
基于numpy.random.randn()与rand()的区别详解
-
基于Python中capitalize()与title()的区别详解
-
基于python for in if 连着写与分开写的区别说明
-
基于params、@PathVariabl和@RequestParam的用法与区别说明
-
针对Android系统的Obad.a与基于Windows的恶意软件的区别
-
QEMU模拟器下编译运行基于RISCV指令集的linux操作系统