内容目录
一,背景
最近突然想研究语言虚拟机到底怎么运行的,于是我网上找了一些资料,稍微记录一下,让自己有一个映像,并不是为了自己写虚拟机。
二,原理[加载程序]
while(true){
取指令
解析指令
执行指令
}
这里也是本文的核心内容, 实际上虚拟机很简单, 遵循这样的模式:
- 读取: 从文件读取内容,解析生成指定集合等等
- 解码: 解析指定指令。【一条条执行,然后读取指令 push eax】
- 执行: 执行解码后的指令 【当读取这个指定,执行 压入一个eax 的值到栈顶】
三,参考资料
用 Lua 实现一个微型虚拟机-基本篇 - 自由布鲁斯 - 博客园 (cnblogs.com)
Felix Angell's personal website
/** This is almost identical to the articles VM **/ #include <stdio.h> #include <stdbool.h> bool running = true; int ip = 0; int sp = -1; int stack[256]; typedef enum { PSH, ADD, POP, HLT } InstructionSet; const int program[] = { PSH, 5, PSH, 6, ADD, POP, HLT }; int fetch() { return program[ip]; } void eval(int instr) { switch (instr) { case HLT: { running = false; printf("done\n"); break; } case PSH: { sp++; stack[sp] = program[++ip]; break; } case POP: { int val_popped = stack[sp--]; printf("popped %d\n", val_popped); break; } case ADD: { // first we pop the stack and store it as a int a = stack[sp--]; // then we pop the top of the stack and store it as b int b = stack[sp--]; // we then add the result and push it to the stack int result = b + a; sp++; // increment stack pointer **before** stack[sp] = result; // set the value to the top of the stack // all done! break; } } } int main() { while (running) { eval(fetch()); ip++; // increment the ip every iteration } }
这是网上文章写的超级简单的虚拟机程序,基本解释了
其他
突然我想起来,我以前写过android 自动化脚本,自己用json定义行为,里面定义很多行文的关键词,然后不断读取这些行为,然后执行对应的行文。这里json其实相当于我们编译器生成的二进制文件。一般编译器生成的他们执行的文件,为什么用二进制表示,只是为了省占用空间。对于我们自己研究,用字符串表示最简单,最好用json或者xml,因为自带描述属性。
这个之前进入设置自己写自动化脚本,内部实现用java驱动,然后用json来描述,这样子可以做做到,动态下发脚本行文,只要底层实现所有指令就可以了,这么说来,我以前也写过商用的虚拟机了。。。。。
上面文章貌似都没有说解析过程,如果还想仔细了解,可以看<自己动手实现lua:虚拟机、编译器>