Skip to content

TIANYU-Sky/Tianyu-Virtual-Machine-Gen.1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tianyu Virtual Machine Gen.1

天宇虚拟机(第一代)

 天宇虚拟机(第一代)包含虚拟机程序与编译器程序。项目开发时间表如下:

项目名称 开始时间 耗时
虚拟机 2019-03 3个月
编译器 2019-05 1个月

虚拟机

  天宇虚拟机采用模拟硬件运行的方式实现,通过解析函数指令进行执行。函数指令与C语言调用函数相同,主要包括:函数名+函数边界+参数+结束符组成,其样式为:function(prama1,prama2,...);
  函数名为指令,分为内存设备网络硬盘程序输入输出运算模块,支持中英文两种指令类型。
  在编写指令参数时,包含设定关键字表达式其他文本类型三种。其他文本类型主要用于在提供路径、IP地址等情况下需要;设定关键字用于为程序提供部分固定的常用表示方法,并用于当前已经预设的设备;表达式是整数型的表达式,使用{}进行包围,可使用+-*/^。其运算符的优先级与日常的四则运算相同,^>*,/>+,-,可以使用()改变其运算顺序。
  因为本虚拟机需要操作内存,所以在表达式中引入[]用于获取当前内存块的数据,以提供多级寻址的能力。在使用[]运算符时,还应该注意,默认取值为64位数据,当需要改变获取内存的长度时,需要使用:运算符。使用规则为[表达式]:+数据长度数据长度规定为:1248,其中,长度为8时可以省略该运算符。   除了指令系统,天宇虚拟机还提供了中断功能,用于为设备IO系统提供及时的数据相应,在当前的系统中,提供了针对常用异常和调用的中断。

  下面将针对具体的指令系统和中断系统进行说明。  

指令系统

  • 内存模块访问指令
中文指令 英文指令 参数列表 说明
设定内存 set 内存空间大小 用于设置程序的初始化大小
申请内存 new 内存块表达式 用于申请信的空闲空间
空间大小
释放内存 free 内存块表达式 用于释放手动申请的空间
初始内存 minit 内存块表达式 用于初始化、批量初始化连续的内存空间
操作数类型
立即数
重复次数
获取时间 tread 内存块表达式 用于获取指定的时间放入到指定的内存区块
时间类型
写入时间 twrite 内存块表达式 用于写入指定的时间
时间类型
时间同步 tsync - 用于同步时间

  • 设备模块指令
中文指令 英文指令 参数列表 说明
激活设备 dact 设备中断号 用于激活指定设备,使设备进入运行状态
暂停设备 dpause 设备中断号 用于暂停设备,使设备进入暂停状态
复位设备 dreset 设备中断号 用于设置设备回复初始化
关闭设备 dclose 设备中断号 用于关闭设备,使设备离线
读设备 dread 设备中断号 用于从设备基础缓冲区中将数据读入新建的内存中
内存块表达式
写设备 dwrite 设备中断号 将数据从指定的内存中写入到指定的设备,
内存块表达式 并触发指定设备的中断服务程序
数据长度

  • 网络模块
中文指令 英文指令 参数列表 说明
新建连接 connect 网络连接编号 用于新建一个网络连接
IP地址
IP端口号
IP地址类型
网络协议
网络连接类型
暂停连接 npause 网络连接编号 用于暂停一个网络连接
恢复连接 nreset 网络连接编号 用于将一个网络连接从暂停中恢复
结束连接 stop 网络连接编号 用于将网络连接终止并释放其占用的资源
获取端口 getport 网络连接编号 获取指定网络连接的服务器/客户端IP地址端口
端口类型
内存块表达式
发送数据 send 网络连接编号 用于将内存中的指定数据发送到指定连接上
内存块表达式
数据长度
接受数据 receive 网络连接编号 从指定连接中获取接收到的数据
内存块表达式

  • 硬盘模块
中文指令 英文指令 参数列表 说明
新建 create 路径 在硬盘中创建指定的目录/文件
文件类型
删除 delete 路径 从硬盘中删除指定的目录/文件
文件类型
打开文件 fopen 文件标志编号 打开指定文件
文件路径
写入方式
关闭文件 fclose 文件标志编号 关闭打开的文件
文件指向 position 文件标志编号 修改文件访问位置
光标指向位置
读文件 fread 文件标志编号 用于将文件中的部分数据读入指定的内存
内存块表达式
读取文件长度
写文件 fwrite 文件标志编号 用于将指定内存块中的数据写入文件
内存块表达式
数据长度
拷贝文件 fcopy 源文件路径 用于拷贝指定文件
目标文件路径

  • 程序模块
中文指令 英文指令 参数列表 说明
本地结束 end - 用于程序最后一条指令结束后的自动处理
启动进程 pinit 文件路径 用于打开文件并创建新进程后执行
结束进程 pend - 结束正在执行的进程
切换进程 pswitch - 用于暂停当前进程并进入下一个进程
加载文件 tinit 加载文件标识 用于打开文件并将代码加载至指令空间
文件路径
结束加载 tend 加载文件标识 从指令空间中移除指定的代码
外部调用 callo 加载文件标识 用于指示程序进入一个新的代码空间中
标识符
本地调用 call 标识符 指示程序进入新的过程,并保存当前的执行位置
结束调用 ret - 结束当前过程,并返回上一个过程
跳转 jmp 标识符 无条件转移指令,进入新过程,但不保存当前执行位置
正跳转 jns 标识符 当运算标识符为正时转移到新的过程,不保存当前执行位置
负跳转 js 标识符 当运算标识符为负时转移到新的过程,不保存当前执行位置
零跳转 jz 标识符 当运算标识符为零时转移到新的过程,不保存当前执行位置
入栈 push 内存块表达式 将指定数据送入公共数据堆栈
出栈 pop 内存块表达式 将公共数据堆栈栈顶返回到指定的内存中

注:当前实例程序尚未加入对多线程、多进程的支持,故线程、进程操作指令无效

  • 输入输出模块
中文指令 英文指令 参数列表 说明
显示输出 print 内存块表达式 用于将指定的内存数据显示在控制台中,采用系统默认编码
数据长度
print 字符串 将字符串输出在控制台中
显示字符 putc 内存块表达式 将指定内存的字符显示在控制台中
键盘输入 scan 内存块表达式 从键盘缓冲区中输入指定长度的数据到内存(内存需要自行申请)
数据长度

  • 运算模块
中文指令 英文指令 参数列表 说明
加法 add 操作数类型 用于将后两个内存块中的指定大小数据相加后保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
减法 sub 操作数类型 用于将后两个内存块中的指定大小数据相减后保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
乘法 mul 操作数类型 用于将后两个内存块中的指定大小数据相乘后保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
除法 div 操作数类型 用于将后两个内存块中的指定大小数据相除后的商保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
求余 mod 操作数类型 用于将后两个内存块中的指定大小数据求余后的余数保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
逻辑与 and 操作数类型 用于将后两个内存块中的指定大小数据按位相与后保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
逻辑或 or 操作数类型 用于将后两个内存块中的指定大小数据按位或后保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
逻辑异或 xor 操作数类型 用于将后两个内存块中的指定大小数据按位异或后保存在第一个内存块
内存块表达式
内存块表达式
内存块表达式
逻辑非 not 操作数类型 用于将内存块中的数据按位取反后保存在原内存块
内存块表达式
随机数 rand 内存块表达式 用于生成一个32位的指定范围的随机数并保存在指定的内存块
起始值
结束值

已定义的关键字

IP类型

4代IP IPv4 IP地址类型 IP地址长度为32位
6代IP IPv6 IP地址长度为128位

协议类型

TCP协议 TCP/IP 协议类型 可靠的传输服务协议
UDP协议 UDP 不可靠的传输服务协议

服务类型

服务器 Server 连接模式 只用于接收数据的连接
客户端 Client 只用于发送数据的连接
混合模式 Mix 可用于发送与接收数据的连接

端口类型

接收端口 Server 端口类型 用于接收数据的端口
发送端口 Client 用于发送数据的端口
自动端口 Auto 自动的端口类型,默认为服务器端口,无服务器时为客户端端口

文件类型

目录 Entry 路径类型 指定路径为目录
文件 File 指定路径为文件

文件操作类型

追加写入 append 文件写入方式 将数据写入到文件的末尾
覆盖写入 cover 从文件指针开始处写入数据并覆盖掉原有数据
新建写入 create 创建新文件并从头写入,如果文件存在则删除

设备状态

设备正常 DS_OK 设备运行状态
设备暂停 DS_PU
设备异常 DS_ER

时间类型

时间年 Year 时间操作类型
时间月 Month
时间日 Day
时间小时 Hour
时间分 Minute
时间秒 Second

系统枚举

  系统枚举是用于模块间调用的指令,包括错误中断以及状态标识,具体如下。

内存异常中断

Mem_Full 内存满异常
Time_Error 时间异常
Over_Flow 内存溢出
Out_Bounds 内存越界

设备异常中断

Add_Failed 设备添加失败
Not_Exist 设备不存在(设备不在设备表中)
Off_Line 设备离线(设备关闭或卸载)
Work_Failed 设备异常
Interrupt_Error 中断异常

网络连接异常中断

Connection_Exist 网络连接已存在
Create_Error 建立连接失败
ReConnection_Err 重连失败
Send_Failed 数据发送失败

符号值

Positive 正数标志
Negative 负数标志
Zore 零标志

设备运行状态

Closed 设备处于关闭状态
Running 设备正在运行
Paused 设备已暂停
Anomalous 设备运行异常

时间类型

时间年 Year
时间月 Month
时间日 Day
时间小时 Hour
时间分 Minute
时间秒 Second

IP类型

4代IP IPv4
6代IP IPv6

协议类型

TCP协议 TCP/IP
UDP协议 UDP

服务类型

服务器 Server
客户端 Client
混合模式 Mix

端口类型

接收端口 Server
发送端口 Client
自动端口 Auto

异常中断号表

  异常中断号是用于程序内部的调用指令,包括错误中断以及系统调用中断,具体的中断如下表所示。其他未显示的中断号为未分配中断,后期的开发中可以进行扩充。

关键字名 助记符
0x00 数学异常-除零中断
0x01 数学异常-计算溢出
0x10 数据异常-数组越界
0x11 数据异常-空地址
0x12 缺页中断
0x13 内存申请中断
0x14 内存释放中断
0x15 获取时间中断
0x16 修改时间中断
0x17 同步时间中断
0x18 系统异常-堆栈溢出
0x19 系统异常-堆栈越界
0x1A 系统异常-内存溢出
0x20 进程切换
0x21 进程结束
0x22 结束正在执行的线程(文件)并回退
0x23 加载进程
0x24 载入线程
0x30 键盘输入
0x31 显示输出
0x33 数据源空
0x40 创建网络连接
0x41 发送数据
0x42 接收数据
0x43 获取网络端口号
0x45 暂停网络连接
0x46 复位网络连接
0x47 关闭网络连接
0x50 设备中断-激活设备
0x51 设备中断-暂停设备
0x52 设备中断-复位设备
0x53 设备中断-关闭设备
0x54 设备中断-读设备
0x55 设备中断-写设备
0x60 打开文件
0x61 关闭文件
0x62 读文件
0x63 写文件
0x64 拷贝文件
0x65 移动指针
0x67 创建文件
0x68 删除文件
0xE0 核心中断-设置时间片
0xE1 核心中断-获取时间片
0xE2 核心中断-获取核心数


  注:部分多线程、多进程相关的中断当前只进行了定义,未进行具体的实现,因此暂时不可使用。部分异常在当前的设置环境中还未被使用。

编译器

PL/0语法

  PL0语法的EBNF表示如下:

<表达式> ::= [+|-]<项>{<加法运算符><项>}
<项> ::= <因子>{<乘法运算符><因子>}
<因子> ::= <标识符>|<无符号整数>|'('<表达式>')'
<加法运算符> ::= + | -
<乘法运算符> ::= * | /
<关系运算符> ::= = | # | < | <= | > | >=
<条件语句> ::= IF<条件>THEN<语句>
<过程调用语句> ::= CALL<标识符>
<当型循环语句> ::= WHILE<条件>DO<语句>
<读语句> ::= READ '('<标识符>{,<标识符>}')'
<写语句> ::= WRITE '('<表达式>{,<表达式>}')'
<字母> ::= a | b | … | X | Y | Z
<数字> ::= 0 | 1 | … | 8 | 9

词法符号

符号 说明
PL0_ConstSym Const
PL0_VarSym Var
PL0_ProcedureSym Procedure
PL0_BeginSym Begin
PL0_EndSym End
PL0_OddSym Odd
PL0_IfSym If
PL0_ThenSym Then
PL0_CallSym Call
PL0_WhileSym While
PL0_DoSym Do
PL0_ReadSym Read
PL0_WriteSym Write
PL0_Dot '.'
PL0_Comma ','
PL0_Semicolon ';'
PL0_Equal '='
PL0_Become ':='
PL0_Plus '+'
PL0_Sub '-'
PL0_LBrace '('
PL0_RBrace ')'
PL0_Mul '*'
PL0_Div '/'
PL0_Nequal '#'
PL0_Less '<
PL0_LessEqual '<='
PL0_Greater '>'
PL0_GreaterEqual '>='
PL0_ID 标识符类型,由字母与数字组成,字母开头
PL0_Number 全部由数字组成
PL0_ERROR 错误单词

语法分析过程

  编译器的语法分析采用自下而上的分析方式,由常量分析开始,以此完成变量、子过程的分析。语法分析进行的同时会根据PL0语法与TYVM指令系统的对应完成目标代码的输出。语法分析器的调用过程图如下:
PL0编译器语法语义分析调用过程图-(READMEIMG/TYVM_Comilper_SCall.png)

说明

编译器

  • Compiler.exe

  Compiler.exe为控制台程序,通过CMD或Power Shell命令完成调用,下表为程序的命令参数。

参数 参数值 说明
-l <directory> 独立的词法分析程序,将词法分析结果输出至控制台
-c <directory> [-o] 执行完整的编译过程,生成.tyh文件,-o为可选参数
-o <outfile> 指定编译输出文件,只能用于-c命令参数之后,如果不使用则输出为默认文件
-h - 获取帮助
  • PL0_Comletion.DLL

PL0_Compeltion.DLL使用C#语言在.Net Standard平台上实现,命名空间为PL0_Completion。

方法一:使用时通过创建Compiler对象完成针对编译器的初始化,通过调用LexAnalysCompiler完成编译。

方法二:通过使用SyntaxAnalysisUnit类和LexAnalysisUnit类完成。当使用该方法时,需注意类的关联。

注:在使用第二种方法时,由于采用了默认的访问策略,可能需要您自行修改部分类的访问控制符,并重新生成该项目。

虚拟机

  天宇虚拟机采用C#语言在.Net Standard平台上实现,基础命名空间为SkyVM,该项目可以放入所有基于C#开发的程序中(项目版本不能低于.netstandard2.0)。在使用时需要将5个模块都加入项目中。如下图所示为TYVM的系统功能框架。
系统功能框架-(READMEIMG/TYVM_VM_SysFramework.png)

模块 文件名 命名空间 功能
分析模块 SkyVM.AnaModule.dll SkyVM.AnaModule 分析模块主要提供文件编译解释和程序段生成功能,用于将文本代码转换为程序可读取的指令
核心模块 SkyVM.CoreModule.dll SkyVM.CoreModule SkyVM.CoreModule.Complexs 核心模块包含数学运算、逻辑运算与复杂运算器,提供基本运算与复杂/用户自定义运算
执行模块 SkyVM.ExModule.dll SkyVM.ExModule 指定模块包含核心控制器与代码执行组件,提供代码执行、数据操作、指令操作控制功能
接口模块 SkyVM.InterfaceModule.dll SkyVM.InterfaceModule 接口模块为数据接口包,包含所有底层原件的数据通讯接口
I/O模块 SkyVM.IOModule.dll SkyVM.IOModule 包含网络与基本输入输出控制器组件

  项目各模块之间通过接口进行连接,使用的接口列表如下所示:

接口名 方法 说明 异常
ICache byte[] Get(long,long,int) 获取指定段页的指定大小数据 使用IMemoryCacheInterrupt提交异常中断,中断值见内存异常中断
void Set(long,long,byte[]) 向指定段页写入数据
void Bad(long,long) 清除缓存中指定段页的数据
MemoryBase MemoryBlock ReadMemory(long,out long) 从内存中读取指定内存块 out值为-1时,内存出现异常,MemoryBlock返回null时出现异常
long ApplyMemory(long, out long) 申请指定大小的内存
void ReleaseMemory(long) 释放指定内存块
IALUnit Symbol_Flag Symbol 获取运算结果符号 符号值见符号值,计算方法返回bool型标志,返回true溢出,否则为未溢出
bye[] Calculate(out bool,string,CalculateParameter[]) 计算方法
bool OperateTest(string) 运算符测试
IDeviceControl void AddDevice(int,IOBase) 添加一个设备 使用IDeviceControlInterrupt提交异常中断,中断值见设备异常中断,设备包含设备运行状态Device_State,具体值见设备运行状态
void DeleteDevice(int) 删除一个设备
object[] GetDevices 获取所有设备
object GetDevice(int) 获取指定中断的设备
void SetInterrupt(int,int) 设置中断号
void AddInterruptService(int,int,string[]) 添加中断服务程序
void DelInterruptService(int,int) 删除指定中断服务程序
void CleanInterruptService(int) 清除指定设备的所有中断服务程序
TimeBase void SyncTime() 同步时间 TimeOperation_Type值见时间类型
short ReadTime(TimeOperation_Type) 读取指定时间
void WriteTime(short,TimeOperation_Type) 写入指定时间
void Save() 保存时间
IOBase void Run() 启动设备 设备基类包含设备状态值,具体值见设备运行状态
void Stop() 停止设备
void Pause() 暂停设备
void Reset() 重置设备
byte[] Get 获取设备数据
byte[] Set 向设备写入数据
INetControl void CreateConnection(string,int,IP_Type,Protocol_Type,Connection_Model) 创建连接 异常通过网络控制器终端接口INetControlInterrupt提交,具体异常值见网络连接异常中断IP_Type类型值见IP类型Protocol_Type协议类型Connection_Model服务类型Prot_Type端口类型
void PauseConnection(int) 暂停连接
void ResetConnection(int) 重置连接
void StopConnection(int) 停止连接
int GetPort(int,Port_Type) 获取连接端口
void Send(int,byte[]) 通过指定连接发送数据
byte[] Receive(int) 从指定连接获取数据
IExecutorControl object Interrupt(int,InterruptCode,object[]) 核心中断请求 执行单元接口用于为底层提供异常请求与数据请求,具体中断说明异常中断表

  • 虚拟机符号表数据结构

虚拟机符号表数据结构-(READMEIMG/TYVM_VM_SymTableDS.png)

  • 虚拟机程序块数据结构

虚拟机程序块数据结构-(READMEIMG/TYVM_VM_ProgramBlockDS.png)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages