本文借鉴《自己动手实现Lua:虚拟机、编译器和标准库》,算是对自己学习的总结,也希望分享下所学知识~~
高级编程语言虚拟机是对真实计算机的模拟和抽象。
指令集(Instruction Set)可以大致分为两类:
1.基于栈(Stack Based)
2.基于寄存器(Register Based)
Java、.Next CLR、Python 都是基于栈的虚拟机
Lua虚拟机时基于寄存器的虚拟机
(Lua 5.0之前使用的基于栈的,之后就改成了基于寄存器的)
区别:
1.基于栈的虚拟机需要使用PUSH类指令往栈顶推入值,使用POP从栈弹出值,其他指令则是对栈顶的值进行操作
指令集相对比较大,但是指令的平均长度比较短
2.基于寄存器的虚拟机由于可以直接对寄存器进行寻址,所以不需要PUSH或者POP类指令,指令集相对较小,但是由于需要把寄存器地址编码进指令里,所以指令的平均长度比较长
(实现方式双方都有利有弊)
按照指令长度是否固定,指令集可以分为两种:
1.定长指令集(Fixed-width)
2.变长指令集(Variable-width)
Java虚拟机使用的是变长指令集,指令长度从1到多个字节不等
Lua则使用的是定长指令集,每条指令占4个子节(共32比特),其中6比特用于操作码(Opcode),其余26比特用于操作数(Operand)
Lua 5.3 一共定义了47条指令,可以分为:
1.加载指令
2.运算符相关指令
3.循环和跳转指令
4.函数调用相关指令
5.表操作指令
6.Upvalue操作指令