返回介绍

02 基于栈的字节码解释执行引擎

发布于 2022-10-22 21:20:36 字数 5667 浏览 0 评论 0 收藏 0

这个栈,就是栈帧中的操作数栈。

解释执行

先通过 javac 将代码编译成字节码,虚拟机再通过加载字节码文件,解释执行字节码文件生成机器码,解释执行的流程如下:

词法分析 -> 语法分析 -> 形成抽象语法树 -> 遍历语法树生成线性字节码指令流

指令集分类

基于栈的指令集

  • 优点:

    • 可移植:寄存器由硬件直接提供,程序如果直接依赖这些硬件寄存器,会不可避免的受到硬件的约束;
    • 代码更紧凑:字节码中每个字节对应一条指令,多地址指令集中还需要存放参数;
    • 编译器实现更简单:不需要考虑空间分配问题,所需的空间都在栈上操作。
  • 缺点: 执行速度稍慢

    • 完成相同的功能,需要更多的指令,因为出入栈本身就产生相当多的指令;
    • 频繁的栈访问导致频繁的内存访问,对于处理器而言,内存是执行速度的瓶颈。
  • 示例: 两数相加

      iconst_1  // 把常量1入栈
      iconst_1
      iadd      // 把栈顶两元素出栈相加,结果入栈
      istore_0  // 把栈顶值存入第0个Slot中
    

基于寄存器的指令集

示例: 两数相加

mov  eax, 1
add  eax, 1

执行过程分析

public class Architecture {
    /*
    calc函数的字节码分析:
    public int calc();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
    stack=2, locals=4, args_size=1 // stack=2,说明需要深度为2的操作数栈
                                   // locals=4,说明需要4个Slot的局部变量表
    0: bipush 100                  // 将单字节的整型常数值push到操作数栈
    2: istore_1                    // 将操作数栈顶的整型值出栈并存放到第一个局部变量Slot中
    3: sipush 200
    6: istore_2
    7: sipush 300
    10: istore_3
    11: iload_1                    // 将局部变量表第一个Slot中的整型值复制到操作数栈顶
    12: iload_2
    13: iadd                       // 将操作数栈中头两个元素出栈并相加,将结果重新入栈
    14: iload_3
    15: imul                       // 将操作数栈中头两个元素出栈并相乘,将结果重新入栈
    16: ireturn                    // 返回指令,结束方法执行,将操作数栈顶的整型值返回给此方法的调用者
    */

    public int calc() {
        int a = 100;
        int b = 200;
        int c = 300;
        return (a + b) * c;
    }

    public static void main(String[] args) {
        Architecture architecture = new Architecture();
        architecture.calc();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击“接受”或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。