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

栈式指令集使用栈来管理运行,寄存器指令集使用寄存器进行工作。

Java 编译得到的字节码指令流,基本上是一种基于栈的指令集架构。

比较:

基于栈的指令集基于寄存器的指令集
可移植性不需要硬件支持,容易跨平台依赖硬件寄存器
性能在内存中操作,相对较慢直接由 cpu 执行,速度快
指令数量因为出栈、入栈操作,完成相同功能所需的指令数量更多相比更少
设计代码相对更加紧凑(大部分指令无参数)
编译器实现更加简单(不需要考虑空间分配的问题,所需空间都在栈上操作)

示例

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

对应字节码:

 0 bipush 100
 2 istore_1
 3 sipush 200
 6 istore_2
 7 sipush 300
10 istore_3
11 iload_1
12 iload_2
13 iadd
14 iload_3
15 imul
16 ireturn

查看字节码显示这段代码需要深度为 2 的操作数栈和 4 个变量槽的局部变量空间。

bipush、sipush都是整型入栈指令,只是针对不同的数值范围。

istore_1 指令的作用是将操作数栈顶的整型值出栈并存放到第 1 个局部变量槽中。

前六条指令都是先入栈到操作数栈中再出栈到局部变量槽中。

1690196272564.png

iload_1 指令的作用是将局部变量表第 1 个变量槽中的整型值复制到操作数栈顶,如上图。

iadd 指令的作用是将操作数栈中头两个栈顶元素出栈,做整型加法,然后把结果重新入栈。

imul 指令与 iadd 指令类似。

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

实际的运作过程并不会完全符合上面的描述,因为虚拟机中解析器和即时编译器都会对输入的字节码进行优化。

最后修改:2023 年 07 月 24 日
如果觉得我的文章对你有用,请随意赞赏