Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

MiniASM —— 一个类 RISC 汇编虚拟机

用 Rust 从零实现的汇编器与虚拟机。包含两趟扫描汇编器、基于寄存器的执行引擎,以及完整的指令集。


特性

  • 两趟扫描汇编器:支持标签(label)、自动地址解析、语法检查
  • 类 RISC 指令集:30 条指令,三地址格式,操作清晰
  • 寄存器架构:11 个通用寄存器(R0–R10),R0 恒零,R10 兼作栈指针
  • 内存与栈:1024 单元内存,栈向高地址生长
  • 函数调用CALL / RET + 硬件栈,支持子程序
  • 条件跳转:基于零标志(Z)和符号标志(S)的 7 种跳转
  • I/O 支持:整数输出 PRINT 与 ASCII 字符输出 PRINTC

快速开始

git clone https://github.com/0x8000S/MiniASM.git
cd MiniASM
cargo run

默认会执行 main.rs 中嵌入的测试程序。你也可以修改 main() 里的 code 字符串来运行自己的汇编代码。


指令集

数据传送

指令格式说明
MOVMOV dst, srcsrc 可以是寄存器或立即数

算术逻辑(三寄存器)

指令格式说明
ADDADD dst, a, bdst = a + b
SUBSUB dst, a, bdst = a - b
MULMUL dst, a, bdst = a * b
DIVDIV dst, a, bdst = a / b(整除,除零报错)
MODMOD dst, a, bdst = a % b
ANDAND dst, a, b按位与
OROR dst, a, b按位或
XORXOR dst, a, b按位异或
SHLSHL dst, a, bdst = a << b
SHRSHR dst, a, bdst = a >> b

比较与一元运算

指令格式说明
CMPCMP a, b比较 ab,更新 Z/S 标志
NEGNEG dst, srcdst = -src
NOTNOT dst, srcdst = !src(按位取反)
INCINC rr += 1
DECDEC rr -= 1

跳转(目标为标签)

指令条件
JMP无条件
JE相等(Z = true)
JNE不等(Z = false)
JG大于(Z = false 且 S = false)
JL小于(S = true)
JGE大于等于(S = false)
JLE小于等于(Z = true 或 S = true)

栈与函数

指令格式说明
PUSHPUSH r将寄存器值压栈
POPPOP r弹栈到寄存器
CALLCALL label调用子程序
RETRET返回

内存访问

指令格式说明
LOADLOAD r, [addr]r = memory[addr_reg]
STORESTORE [addr], rmemory[addr_reg] = r

I/O 与系统

指令格式说明
PRINTPRINT r以整数形式输出,带换行
PRINTCPRINTC r以 ASCII 字符形式输出,不换行
HALTHALT停机

示例:计算 1+2+…+10

_start:MOV R1,0 ; sum = 0MOV R2,1 ; i = 1MOV R3,10 ; max = 10loop:CMP R2, R3JG doneADD R1, R1, R2 ; sum += iMOV R4,1ADD R2, R2, R4 ; i += 1JMPloopdone: PRINT R1 ; 输出 55 HALT

示例:函数调用

_start:MOV R1,7CALL double PRINT R1 ; 输出 14 HALTdouble:MOV R2,2MUL R1, R1, R2RET

示例:内存读写

_start:MOV R1,100 ; 地址MOV R2,42 STORE [R1], R2 ; memory[100] = 42 LOAD R3,[R1] ; R3 = memory[100] PRINT R3 ; 输出 42 HALT

架构概览

汇编源码
│
▼
[汇编器] ──→ 第一趟:收集标签地址
│ ──→ 第二趟:生成指令序列
▼
指令序列 (Vec<Inst>) + 入口地址
│
▼
[虚拟机] ──→ Fetch → Decode → Execute 循环
│
▼
执行结果
  • 寄存器:R0(恒零)、R1–R9(通用)、R10(SP)
  • 内存:1024 个 i64 单元,栈与数据区共享
  • 标志位:Z(零标志)、S(符号标志)

注意事项

  • 标签必须独占一行,以冒号结尾,例如 loop:
  • 程序入口为 _start: 标签;若不存在,默认从第 0 条指令开始。
  • 算术指令(ADD/SUB 等)的源操作数只能是寄存器,立即数需先用 MOV 载入。
  • 注释以分号 ; 开头。

About

一个类 RISC 汇编虚拟机

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages