概述
这个虚拟机作为我的TinyOs计划的理论准备。我的TinyOs在计划中是一个运行在GBA上面的32位的多任务操作系统。多任务是通过多个虚拟机的切换实现的。作为技术准备,我打算在PC上面实现一个简单的32位精简指令虚拟机,然后在这个虚拟机的基础上,实现一个多虚拟机的任务切换。这样的话,我的开发和调试可以变得更加简单,当任务切换实现以后,我再把这个多虚拟机的系统,移植到GBA上面去。(这里使用32位和精简指令都是为了适应GBA的环境。)
指令集定义
于是,我定义了一个最简单的指令集,如下:
机器码 |
指令格式 |
简单解释 |
0 |
T_NOP |
T_NOP |
T_NOP |
空指令,无任何意义,直接执行下一句 |
1 |
T_MOV |
op0 |
op1 |
传输指令,把op1地址内容送至op0地址 |
2 |
T_ADD |
op0 |
op1 |
加法指令,把op0地址内容和op1地址内容相加,结果送至op0地址 |
3 |
T_CMP |
op0 |
op1 |
比较指令,比较op0和op1地址内容,如果<那么寄存器Cmp置0,否则寄存器Cmp置1 |
4 |
T_JMP |
op0 |
T_NOP |
无条件条转指令,跳转到op0这个地址 |
5 |
T_JCP |
op0 |
op1 |
比较跳转指令,寄存器Cmp为0,跳转到op0,寄存器Cmp为1,跳转到op1 |
6 |
T_PUS |
op0 |
T_NOP |
压栈指令,把op0地址的内容压栈 |
7 |
T_POP |
op0 |
T_NOP |
出栈指令,出栈到op0地址 |
8 |
T_HLT |
T_NOP |
T_NOP |
关机指令,关闭虚拟机 |
9 |
T_PUT |
op0 |
op1 |
屏幕输出指令,在屏幕op0内容/20,op0内容%20的位置,用op1内容代表的颜色画点 |
注解:操作数为T_NOP代表改操作数无意义,可以为任何数。
屏幕暂时的尺寸定义为20*20点阵,支持24位真彩。因为时间和汇编代码里面暂时不需要的原因,T_PUS ,T_POP ,T_HLT 三个指令,在这个版本里面并没有实现。
汇编程序编写
地址 |
指令 |
操作数0 |
操作数1 |
注释 |
00 |
T_JMP |
12 |
0 |
直接跳转到12,因为03-11都是给变量预分配的 |
03 |
0 |
1 |
0 |
3、5是一个变量 4、6是用来累加的常量 7、8是用来做越界检测的常量 |
06 |
10 |
400 |
16777216 |
09 |
0 |
0 |
0 |
12 |
T_NOP |
T_NOP |
T_NOP |
空指令 |
15 |
T_PUT |
2 |
2 |
在屏幕的0点画颜色为0的点,因为地址2保存的数是0 |
18 |
T_ADD |
3 |
4 |
对变量3进行加1操作 |
21 |
T_ADD |
5 |
6 |
对变量5进行加10操作 |
24 |
T_CMP |
3 |
7 |
比较变量3的值和常量7的值 |
27 |
T_JCP |
30 |
33 |
分别跳转到30和33 |
30 |
T_JMP |
36 |
0 |
直接跳转到36 |
33 |
T_MOV |
3 |
2 |
给变量3赋0值 |
36 |
T_CMP |
5 |
8 |
比较变量5的值和常量8的值 |
39 |
T_JCP |
42 |
45 |
分别跳转到42和45 |
42 |
T_JMP |
48 |
0 |
直接跳转到48 |
45 |
T_MOV |
5 |
2 |
给变量5赋0值 |
48 |
T_PUT |
3 |
5 |
在变量3指定的位置,画上变量5指定的颜色 |
51 |
T_JMP |
18 |
0 |
无条件跳转到18 |
虚拟机的PC实现
为了关注核心问题,我做了大量的简化,在目前这个虚拟机模型里面,除了Ip(指令指针寄存器),Cmp(比较寄存器)以外,没有定义任何其他的寄存器。任何运算和操作都是在32位的地址空间里面进行的。
首先我定义了一个全局数组ASM用来保存我写的汇编程序,用宏定义的做法,可以让你觉得这个数组就是一个简单的汇编编辑器了。然后,利用核心代码RunEnmu()来运行汇编程序。下面是核心的实现代码:

因为这个实现很简单,我就不说什么细节了,有什么疑问可以在后面留言。
你可以在下面地址下载到完全的代码和可执行程序(BCB的,相信可以很容易的移植到VC):
http://www.tinydust.net/gba-os/Emu.zip
运行截图如下:
想了解更多关于GBA TinyOS请浏览Tiny的GBA开发专栏。
http://blog.codelphi.com/tinyfool/category/402.aspx
想了解Tiny,请浏览Tiny的网站。
http://www.tinydust.net/ 
|