工具链架构

从源码到可执行文件的完整工具链流程

输入
.c.bas.py .rs.go .java.cs
↓ VMLTool (主工具,GCC 风格 CLI) ↓
IR
VML 汇编 (.vml)
↓ VMLAssembler ↓
二进制
VMB 二进制 (.vmb)
↙ VMLRuntime 执行 | VMLTranslator 翻译 | VMLPacker 打包 ↘
输出
控制台输出 目标汇编 独立 EXE

VMLTool — 主命令行工具

GCC 风格 CLI,自动根据扩展名选择编译器

GCC 风格命令(推荐)

命令说明
vmltool input.c -o output.vml编译 C 为 VML
vmltool input.c -o output.hex -t avr -f hexC → AVR HEX 一键烧录
vmltool -S input.c -o output.s -t arm-cmC → ARM 汇编(仅生成汇编)
vmltool -E input.c仅预处理(展开宏和 include)
vmltool -c input.c -o out.vml -D DEBUG -O2 -WallGCC 兼容编译选项
vmltool -v显示版本信息
vmltool -r program.vml运行 VML 程序

使用示例 — 完整工作流

# 1. 编译 C 源码为 VML
$ vmltool hello.c -o hello.vml
已编译: hello.c → hello.vml (120 条指令)

# 2. 直接运行 VML 程序
$ vmltool -r hello.vml
Hello from C!

# 3. 一键编译+运行
$ vmltool hello.py -r
Hello from Python!

# 4. 交叉编译到 AVR 并生成 HEX
$ vmltool blink.c -o blink.hex -t avr -f hex

VMLAssembler — 汇编器

将 VML 汇编文本编译为 VMB 二进制格式

核心功能

  • 标签解析与地址计算
  • 伪指令处理 (.entry / .stack / .vectors / .include)
  • 表达式求值 (常量折叠)
  • 库链接 (.include 嵌套包含)
  • VMB 二进制序列化
  • VMB → VML 反汇编

输入 → 输出示例

; 输入: hello.vml
.entry main
LABEL main
    MOVE R0, #72     ; 'H'
    SYSCALL #0       ; putchar
    HALT

; 输出: hello.vmb (二进制)
; 头 24 字节 + 指令序列
; MOVE = OpCode 1, R0=0, #72=72
; SYSCALL = OpCode 42, #0=0

OpCode.cs — 唯一权威定义

VMLAssembler/OpCode.cs 是 VML 操作码的唯一权威定义。所有 92 个操作码的枚举值和语义在此文件中定义。C 运行时头文件必须与之保持同步。

VMLToHex — MCU 烧录工具

从源码到 HEX 固件的一站式工具,16 个目标架构,6 种输出格式

完整命令参考

命令说明
vml2hex main.c -arch avrC → VML → AVR → HEX(全自动)
vml2hex main.bas -arch 8051BASIC → VML → 8051 → HEX
vml2hex main.py -arch arm-cmPython → VML → STM32 → HEX
vml2hex program.vml -arch avrVML → AVR → HEX
vml2hex blink.c -arch arm-cm --chip stm32f429 -f hexSTM32 指定芯片型号烧录

优化等级

参数说明
-O0不优化 — 调试用,保留所有指令
-O1死代码消除 + 常量折叠 — 默认
-O2O1 + 复制传播 + 循环优化 — 生产发布

输出格式

参数格式用途
-f hexIntel HEX烧录(默认)
-f binBinary裸二进制镜像
-f s19Motorola S19Freescale 烧录器
-f elfELFGDB 调试 / objdump 反汇编
-f exeDOS EXEDOS 可执行文件
-f dumpText Dump人类可读文本

STM32 完整烧录流程

# 1. 编译 C 源码 → ARM HEX
$ vml2hex blink.c -arch arm-cm --chip stm32f429 -f hex -o blink.hex

# 2. ST-LINK 烧录
$ STM32_Programmer_CLI -c port=SWD -w blink.hex -v -rst

# 3. 或者输出 ELF 用于 GDB 调试
$ vml2hex blink.c -arch arm-cm -f elf -o blink.elf
$ arm-none-eabi-gdb blink.elf

VMLPacker — 程序打包工具

将 VML/VMB 程序打包为独立可执行文件,支持跨平台分发

使用说明

命令说明
vmlpacker input.vml汇编并运行
vmlpacker input.vml -o out.vmb打包为 VMB 二进制
vmlpacker input.vml --vmb打包为 VMB
vmlpacker input.vml --exe生成当前平台独立 EXE
vmlpacker input.vml --exe linux-x64交叉打包为 Linux EXE
vmlpacker input.vml --run汇编并立即运行

EXE 生成流程

1
VML 程序→ 汇编
↓ VMLAssembler ↓
2
VMB 二进制嵌入资源
↓ dotnet publish --self-contained ↓
3
独立可执行文件

C 运行时版本

VMLFast/VMLPackerC/ 提供 C 语言版本的打包工具:vmlpacker (VML→VMB) 和 vmlexe (VMB→EXE),静态编译后体积更小。

GenLib — 静态共享库管理工具

从 C 源码自动编译 VML 共享库,为 22 种语言生成模块包装和绑定代码

使用说明

命令说明
genlib -A一键全流程:编译 + 模块包装 + 聚合文件 + 源文件绑定
genlib -b增量编译 Lib/shared/src/*.c → .vml
genlib -m -l python为 Python 生成模块包装 .vml
genlib -a -l go生成 Go 语言的 builtin/stdlib/vmllib 聚合文件
genlib -g -l rust -p mylib生成 Rust 绑定 shared.rs,包名 mylib
genlib -s扫描所有导出函数

流水线步骤

1
C 源码Lib/shared/src/*.c
↓ genlib -b (进程内调用 CCompiler) ↓
2
VML 共享库Lib/shared/*.vml
↓ genlib -m (模块包装) ↓
3
模块 .vmlLib/{lang}/*.vml
↓ genlib -a (聚合) + genlib -g (绑定) ↓
4
builtin/stdlib/vmllib + shared.{ext}

模块分层

类型模块进入聚合文件使用方式
coremath, string, time, file, console, system是.include "math.vml" 或自动链接
custom用户自写模块否仅 .include "xxx.vml"

JSON 配置自动生成

Lib/modules.json 和 Lib/naming.json 缺失时自动生成,删了也能重建。

GenDyn — 动态库绑定生成器

扫描 .dylib/.so/.dll 导出符号,生成 VML FFI 包装器和 22 种语言调用绑定

使用说明

命令说明
gendyn -A -n demodll一键全流程:扫描 + 构建 + 包装 + 绑定
gendyn -s扫描动态库导出符号 → dynlibs.json
gendyn -b -n mylib编译 C 胶水代码为共享库
gendyn -w -n mylib生成 VML FFI 包装器 → Lib/dynamic/mylib.vml
gendyn -g -l python -n mylib为 Python 生成绑定 → Lib/python/ext/libmylib.py
gendyn -A -n mylib -H mylib.h全流程 + 指定头文件获取类型信息

FFI 调用链路

1
VML 程序CALL mylib_init
↓ dl_open (SYSCALL #370) + dl_sym (SYSCALL #371) ↓
2
VML 包装器Lib/dynamic/{name}.vml
↓ NativeCallEx (SYSCALL #376) ↓
3
原生 .dylib / .so / .dll

输出路径(与静态库隔离)

文件类型静态库 (GenLib)动态库 (GenDyn)
VML 文件Lib/{lang}/{module}.vmlLib/dynamic/{name}.vml
语言绑定Lib/{lang}/shared.{ext}Lib/{lang}/ext/lib{name}.{ext}
JSON 配置Lib/modules.jsonLib/dynamic/dynlibs.json

GenDev — 设备代码生成器

从 XML 设备描述文件自动生成 22 种语言设备驱动代码

使用说明

命令说明
gendev -i ATmega328P.xml -o atmega328p.h -l c生成 C 头文件
gendev -i ATmega328P.xml -d Generated -a生成所有 22 种语言
gendev ATmega328P.xml -l basic生成 BASIC 代码
gendev ATmega328P.xml -l python生成 Python 代码

XML 设备描述输入

<!-- ATmega328P.xml 示例结构 -->
<Device>
  <Metadata>
    <Name>ATmega328P</Name>
    <Architecture>AVR</Architecture>
    <RAM>2048</RAM>
    <ROM>32768</ROM>
  </Metadata>
  <Registers>
    <Register name="PORTB" address="0x25" />
    <Register name="DDRB"  address="0x24" />
    <Register name="PINB"  address="0x23" />
  </Registers>
  <Peripherals>
    <Timer name="TIMER0" bits="8" />
    <UART name="USART0" />
  </Peripherals>
</Device>

生成代码示例

C 输出
Python 输出
BASIC 输出
// atmega328p.h — 自动生成
#define PORTB (*(volatile unsigned char*)0x25)
#define DDRB  (*(volatile unsigned char*)0x24)
#define PINB  (*(volatile unsigned char*)0x23)

// 外设初始化函数
void timer0_init(unsigned char prescaler);
void usart0_init(unsigned int baud);
# atmega328p.py — 自动生成
PORTB = 0x25
DDRB  = 0x24
PINB  = 0x23

def timer0_init(prescaler):
    pass  # VML MMIO 操作

def usart0_init(baud):
    pass
' atmega328p.bas — 自动生成
CONST PORTB = &H25
CONST DDRB  = &H24
CONST PINB  = &H23

SUB timer0_init (prescaler)
    ' VML MMIO 操作
END SUB