通过一个算术代码来了解栈的解释器执行过程
基于栈指令集Demo
演示1+1基于栈的指令集
iconst_1
iconst_1
iadd
istore_0
两条iconst_1指令连续把两个常量压入栈后,iadd指令把栈顶的两个值出栈、相加、然后方位栈顶,最后istore_0把栈顶的值放到局部变量表的第0个solt中。
基于寄存器指令集Demo
同样演示1+1
mov eax,1
add eax,1
mov指令把EAX寄存器的值设为1,然后add指令再把这个值加1,结果就保存在EAX寄存器里面。
两种方式各有优缺点,基于栈的指令集很明显可移植高,但是工作效率较低。而基于寄存器指令集寄存器由硬件直接提供,工作效率高,程序受硬件约束。
public int calc(){
int a=100;
int b=200;
int c=300;
return (a+b)*c;
}
-------------------------------------------
Classfile /C:/Users/yssq/Desktop/Calc.class
Last modified 2019-11-22; size 274 bytes
MD5 checksum 2681512ec7a4d5b2f6ce595823b43360
Compiled from "Calc.java"
public class me.zhyx.jvm.Calc
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#12 // java/lang/Object."<init>":()V
#2 = Class #13 // me/zhyx/jvm/Calc
#3 = Class #14 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 calc
#9 = Utf8 ()I
#10 = Utf8 SourceFile
#11 = Utf8 Calc.java
#12 = NameAndType #4:#5 // "<init>":()V
#13 = Utf8 me/zhyx/jvm/Calc
#14 = Utf8 java/lang/Object
{
public me.zhyx.jvm.Calc();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 8: 0
public int calc();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=1
0: bipush 100 #单字节的整型常量值(-128-127)推入操作数栈顶
2: istore_1 #将栈顶int型数值存入第二个局部变量
3: sipush 200 #将一个短整型常量值(-32768~32767)推送至栈顶
6: istore_2
7: sipush 300
10: istore_3
11: iload_1 #将第三个int型局部变量推送至栈顶
12: iload_2
13: iadd #将栈顶两int型数值相加并将结果压入栈顶
14: iload_3
15: imul
16: ireturn #从当前方法返回int
LineNumberTable:
line 10: 0
line 11: 3
line 12: 7
line 13: 11
}
SourceFile: "Calc.java"