Skip to content

Latest commit

 

History

History
101 lines (87 loc) · 4.4 KB

Thoughts.md

File metadata and controls

101 lines (87 loc) · 4.4 KB

专栏设想

等GacUI 1.0 release之后,当做完新的parser gen和Gac UI中intellisense的支持之后,写一个专栏,从模拟一台电脑开始,一步一步做到动态语言。

虚拟机

  • 拥有固定大小的内存、硬盘空间和显示器,有足够的指令和中断去操作他们,所有缓存都从内存中切割出来。
  • 虚拟机启动的时候从硬盘的0位开始加载程序,然后执行。
  • 设置好系统堆栈的位置。
  • 0-7为非法内存值,此处浪费一点空间。
  • [8, 1024)为保留空间,这段空间可以被R/W系列之令随意操作。这段空间的每一个位置都有指定的功能,以后再设计。
  • 虚拟机加载程序之后,程序会要求在1024之后再保留一段空间被使用。

64位指令集 (58)

  • 寄存器:r0, r1, f0, f1, s0, s1, i0(当前指令), i1(下一条指令), ef(异常处理帧), en(异常编号),t0(保存所有额外信息)
  • 执行i指向的指令的时候,分别
    • 译码
    • i1指向下一条指令
    • 执行译码后的结果
    • i1复制进i0
  • 每次跳转的时候,i0和i1都会指向同一个值,即跳转目标

读写寄存器 (14)

  • LDI {int64}: 加载一个整数到r0。
  • LDF {double}:加载一个浮点数到f0。
  • R1, R2, R4, R8, RF4, RF8:把r1指向的内存中的数据按不同的类型写进0号寄存器。
  • W1, W2, W4, W8, WF4, WF8:把0号寄存器的内容按不同的类型写进r1指向的内存中。

寄存器复制 (4)

  • I2F:从f0转整形到r0。
  • F2I:从r0转浮点到f0。
  • SWPI:r0和r1交换。
  • SWPF:f0和f1交换。

数学运算 (21)

  • ADDS, ADDU, ADDF:加法,结果存放在0号寄存器。
    • 还有SUB, MUL, DIV, MOD(没有浮点)
    • AND, OR, XOR(无符号整数)
    • NEG(*-1)
    • REV(^0xFFFFFFFF,无符号整数)

比较运算 (4)

  • CS, CU, CF:把0和1号寄存器的数据进行比较,结果写进r0(小于为-1,等于为0,大于为1)。
  • C0:把r0与0进行比较,如果不等于0,把r0改写为0xFFFFFFFF。

跳转 (6)

  • JZN:当r0为0的时候,把i1写进r0,跳转到地址(r0+有符号整数r1的结果)。
  • JZF:当r0为0的时候,把i1写进r0,跳转到地址(r1)。
  • CALL {int64}:利用r0保存的地址信息,在堆栈上开辟足够的空间,并且留出参数那么大的自由空间。空间超出了t0指向的描述的限制则溢出。
  • RET:撤销上一次CALL的堆栈分配并返回到CALL指令记录下来的r0地址。如果r0为0xFFFFFFFF,则关机。
  • LDS:把s1复制进r0。假设CALL指令为x,那么[r0, r0+x)为堆栈的自由空间,可任意修改。
  • THRD:把所有寄存器的值保存进t0的描述,把t0改为r0,把t0描述的值复制回所有寄存器,继续运行。

硬件访问 (3)

  • INIT {int64}:初始化。
    • s0设置为可用内存最大值
    • r0r1f0f1清0
    • 开辟堆栈空间的return address和old s0都为0xFFFFFFFF
    • ef为0
    • en为-1
  • HALT:关机。
  • INT {int64}:执行中断。中断号码为指令参数,r0作为附加参数。所有硬件信息都由INT来完成

异常处理

  • ef指向的结构:|exception handler address|old ef|
  • 每次触发异常的时候,都会
    1. 复制所有寄存器的值
    2. 如果en不为-1,直接蓝屏
    3. 把ef指向的异常处理地址保留下来
    4. POPEF
    5. 跳转到指定的地址

异常处理指令 (6)

  • LDE:把保存异常信息的地址复制到r0,把异常编号复制到r1。r0指向的结构为|r0|r1|f0|f1|s0|s1|i0|i1|ef|en|
  • ERR:抛出6号异常。
  • CLRERR:把en设置为-1,结束异常处理。
  • THROW:放弃异常处理,执行RET,但是不跳转,重新触发一次异常(从第3步开始)。
  • PUSHEF:把地址(i1+有符号整数r0的结果)和其他信息,存放到r1指定的地址中,并把r1复制进ef。
  • POPEF:PUSHEF的反向操作。

异常编号

  1. 堆栈溢出,无法异常处理,直接蓝屏
  2. 内存读写越界
  3. 跳转地址越界
  4. 非法指令(二进制)
  5. 整数除0
  6. 触发异常的时候en不为-1,无法处理异常,直接蓝屏
  7. 主动抛异常

堆栈结构

s1                               s0
|                                |
|free space|return address|old s0|

下一步

  • 超级简单的多任务单线程操作系统
  • 文件系统
  • 内存管理(malloc、free)
  • 屏幕管理
  • 简化后的C语言编译器(外部)