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

现代JVM在执行Java代码的时候,通常都会将解释执行与编译执行两者结合起来
所谓解释执行,就是通过解释器来读取字节码,遇到相应的指令就去执行该指令。
所谓编译执行,就是通过即时编译器(Just In Time,JIT) 将字节码转为本地机器码来执行;现代JVM会根据代码热点来生成相应的本地机器码。

基于栈的指令集与基于寄存器的指令集直接的关系
1、JVM执行指令时所采取的方式是基于栈的指令集
2、基于栈的指令集主要的操作有入栈与出栈两种。
3、基于栈的指令集的优势在于它可以在不同平台之间进行移植,而基于寄存器的指令集是与硬件架构紧密关联的,无法做到可移植。
4、基于栈的指令集的缺点在于完成相同的操作,指令数量通常要比基于寄存器的指令集数量要多;基于栈的指令集是在内存中完成操作的,
而基于寄存器的指令集是直接由CPU来执行的,它是在高速缓冲区进行执行的,速度要快很多。虽然虚拟机可以采用一些优化手段,
但总体来说,基于栈的指令集的执行速度要慢一些。

如对数字2-1的操作,基于栈和基于寄存器的区别

基于栈的指令
1.iconst_1 //将减数1压入栈顶
2.iconst_2 //将被减数2压入栈顶
3.isub //将栈中最上面的两个元素(2和1)弹出来,执行2-1的操作,将2-1的结果1压入栈顶
4.istore_0 //将1放入局部变量表的第0个位置上。

基于寄存器
mov 将2放入寄存器,
sub 后面跟一个参数1,在现有的寄存器上减去1,在把结果放回寄存器。

JVM指令集实例

创建MyTest8.java类

public class MyTest8 {

    public int myCalculate(){
        int a = 1;
        int b = 2;
        int c = 3;
        int d = 4;
        int result = (a + b - c) * d;
        return  result;
    }
}

  使用jclasslib查看myCalculate方法

这21条指令就是myCalculat方法的操作步骤

0 iconst_1   //将1放入操作数栈顶
1 istore_1   //弹出操作数栈顶元素,并把元素的值复制到本地变量表索引为1的位置。
2 iconst_2   //将2放入操作数栈顶
3 istore_2   //弹出操作数栈顶元素,并把元素的值复制到本地变量表索引为2的位置。
4 iconst_3   //将3放入操作数栈顶
5 istore_3   //弹出操作数栈顶元素,并把元素的值复制到本地变量表索引为3的位置。
6 iconst_4   //将4放入操作数栈顶
7 istore 4     //弹出操作数栈顶元素,并把元素的值复制到本地变量表索引为4的位置。
9 iload_1     //从本地变量表中索引为1的值压入操作数栈
10 iload_2   //从本地变量表中索引为2的值压入操作数栈
11 iadd  //弹出操作数栈最上层的两个元素,进行加操作(1+2),将结果3压入操作数栈
12 iload_3   //从本地变量表中索引为3的值压入操作数栈
13 isub        //弹出操作数栈最上层的两个元素,进行减操作(3-3),将结果0压入操作数栈
14 iload 4    //从本地变量表中索引为4的值压入操作数栈
16 imul       //弹出操作数栈最上层的两个元素,进行乘法操作(0 * 4),将结果0压入操作数栈
17 istore 5    //弹出操作数栈顶元素,并把元素的值复制到本地变量表索引为5的位置。
19 iload 5    //从本地变量表中索引为5的值压入操作数栈
21 ireturn    //弹出当前操作数栈顶元素,将值压到调用者的操作数栈中。当前操作数栈的所有元素都将被丢弃。

本地变量表如下图

原文地址:https://www.cnblogs.com/linlf03/p/11109479.html

时间: 2024-08-25 19:31:05

基于栈的指令集与基于寄存器的指令集的区别的相关文章

基于栈的虚拟机字节码执行引擎

一.虚拟机字节码执行引擎概述 虚拟机字节码执行引擎主要就是研究字节码指令具体怎样被执行.对于物理机器,指令的执行是直接建立在OS和硬件的基础上 对于字节码指令的执行就是直接建立在JVM上,然后通过JVM完成具体的字节码指令到机器指令的过程.一般来说虚拟机的执行的 字节码指令是基于栈的不是采用寄存器,主要考虑的原因跨平台. 虚拟机的执行引擎是有JVM规范定义的,可以自己定义指令集以及执行引擎来执行字节码指令.不同的JVM执行引擎的实现可能不同 总体来说一个线程对应的是一个虚拟机栈:线程代码中调用的

基于栈的二叉树的遍历

基于栈的深度优先搜索 基于手写的栈和STL栈的深度优先 //基于系统栈的二叉树的中序遍历 #include <iostream> #include <stack> using namespace std; struct Node { int data; Node* left; Node* right; Node(int val):data(val),left(NULL),right(NULL){}; }; struct Tree { Node* tnode; Tree(Node*

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

Java编译器输出的指令流,基本上[1]是一种基于栈的指令集架构,它们依赖操作数栈进行工作 与之相对的另外一套常用的指令集架构是基于寄存器的指令集 举个最简单的例子,分别使用这两种指令集计算“1+1”的结果,基于栈的指令集会是这样子的: //基于栈的指令 iconst_1 iconst_1 iadd istore_0 //基于寄存器指令 mov eax,1 add eax,1 基于栈的指令集主要的优点就是可移植, 缺点是执行速度慢,相同操作指令数要多很多. 寄存器由硬件直接提供[2],程序直接依

虚拟机字节码操作引擎-----基于栈的字节码解释引擎

虚拟机调用方法可以有解析和分派两种方式,那么虚拟机是如何执行方法中的字节码指令的? 1.解释执行   谈是解释执行还是翻译执行没有意义了,只有确定了某种具体的java实现版本和执行引擎运行模式时,谈解释执行还是编译执行才比较贴切. 如今,基于物理机.java虚拟机,或者非Java的其他高级语言虚拟机的语言,大多都会遵循这种基于现代经典编译原理的思路,在执行前先对程序源码进行词法分析和语法分析处理,把源码转化为抽象语法树 .对于一门具体语言的实现来说,词法分析.语法分析以致后面的优化器和目标代码生

C#编程(七十六)----------使用指针实现基于栈的高性能数组

使用指针实现基于栈的高性能数组 以一个案例为主来分析实现方法: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 基于堆栈的数组 { class Program { static void Main(string[] args) { int[] i = new int[10]; Console.W

基于NodeJS的全栈式开发(基于NodeJS的前后端分离)

也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离) 前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图探索一条全新的前后端分离模式. 随着不同终端(Pad/Mobile/PC)的兴起,对开发人员的要求越来越高,纯浏览器端的响应式已经不能满足用户体验的高要求,我们往往需要针对不同的终端开发定制的版本.为了提升开发效率,前后端分离的需求越

Linux (x86) Exploit系列之三 Off-By-One 漏洞 (基于栈)

Off-By-One 漏洞 (基于栈) 原文地址:https://bbs.pediy.com/thread-216954.htm 什么是off by one? 将源字符串复制到目标缓冲区可能会导致off by one 1.源字符串长度等于目标缓冲区长度. 当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上方.这里由于目标缓冲区位于堆栈中,所以单个NULL字节可以覆盖存储在堆栈中的调用者的EBP的最低有效位(LSB),这可能导致任意的代码执行. 一如既往的充分的定义,让我们

Oracle 基于事务的临时表在11g和12C下的区别

Oracle 基于事务的临时表在11g和12C下的区别下,可以看到收集临时表的统计信息后,前者记录被清空,后者没有,这是个很重要的区别.在公司环境上用的是12C,在现场用的是11g,使用临时表会造成时快时慢,之前我有帖子http://blog.csdn.net/stevendbaguo/article/details/39964807,用了hint之后,也不是特别好,于是直接采集,结果临时表被清空.解决的方法是:建基于session的临时表,且每次用完之后要truncate,要不然,会有问题.

聚类:层次聚类、基于划分的聚类(k-means)、基于密度的聚类、基于模型的聚类

一.层次聚类 1.层次聚类的原理及分类 1)层次法(Hierarchicalmethods)先计算样本之间的距离.每次将距离最近的点合并到同一个类.然后,再计算类与类之间的距离,将距离最近的类合并为一个大类.不停的合并,直到合成了一个类.其中类与类的距离的计算方法有:最短距离法,最长距离法,中间距离法,类平均法等.比如最短距离法,将类与类的距离定义为类与类之间样本的最短距离. 层次聚类算法根据层次分解的顺序分为:自下底向上和自上向下,即凝聚的层次聚类算法和分裂的层次聚类算法(agglomerat