编程语言虚拟机基本原理学习

一,背景

最近突然想研究语言虚拟机到底怎么运行的,于是我网上找了一些资料,稍微记录一下,让自己有一个映像,并不是为了自己写虚拟机。

二,原理[加载程序]

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:虚拟机、编译器>