# 扫描周期 vm 模块:寄存器虚拟机。CMake 目标:`vm`(`STATIC`),只依赖 [`指令与映像.md`](../isa/指令与映像.md)。 运行时是 **一台 VM、一个入口、一份映像**。不链接 `compiler`。扫描周期与确定性见 [`初步计划.md`](../初步计划.md) 第 2、8 节。 ## 扫描周期 ```text 1. 按 sidecar 的 io 绑定,采样 → I / 输入全局 2. 从 PROGRAM MAIN 的 pc=0 执行到 RET 3. 写回 Q / 输出全局 4. 用本周期 Δt 推进 TON / TOF / CTU(不用 wall clock) ``` ## 边界 - 只认 `isa` 映像;类型与溢出按 [`指令与映像.md`](../isa/指令与映像.md)(`INT` 饱和) - 局部 / `VAR` = 固定寄存器;`nregs` 在函数头 - `CALL` 目标是立即数 `fn_id`,有界调用栈 - 无 GC、无堆、无线程;每周期受 `cycle_limit` 限制 - I/O 从哪来、Δt 谁给、回放怎么喂,属于 `BytecodeExecutor`(读 `.stb` + sidecar) --- ## 可观察性接口(v1 预留) TUI 是执行器(`BytecodeExecutor`)的界面,用途是方便观察 VM 运行状态。**v1 不做 TUI**,只预留接口,避免后续改 VM 的观察面。原则: - **数据与展示分离**:`vm` 只提供只读观察 API(数据);TUI 渲染与文本输出属于 `executor`(展示)。vm 不画任何界面。 - **只读轮询**:TUI 通过快照轮询,绝不写 VM 状态;"继续 / 单步"是 executor 侧命令,不改变确定性。 - **快照 POD 化**:快照保持简单数据(将来跨进程 TUI 可序列化)。 建议的 API 形态(12.9 实现时冻结签名,本节只定方向): ```cpp struct Snapshot { uint32_t pc; // 当前指令下标(相对函数字节码段) uint32_t fn_id; // 当前函数 uint32_t cycle_count; // 本周期已执行指令数 uint32_t call_depth; // 调用栈深度 // 寄存器 / I / Q / M / 全局 / FB 字段 的只读视图 }; bool step(); // 精确执行一条指令,停在指令边界 const Snapshot& snapshot() const; ``` - 寄存器 ≤256、映像很小,快照拷贝成本可忽略。 - 单步、回放、dump 都建立在同一套观察 API 上。