Files
Interpreter/Doc/isa/stb文件格式.md
T
Admin 7745dadd2d 阶段1-3:stb文件格式.md 重写为 V2 结构(头 128B/槽表段/值段/元数据段)
- 段序:常量表→函数表→字节码→槽表段→值段→元数据段→SHA
- 头 128B 全字段表(version=2、n_slots/values_size/offset_meta/max_stack)
- 常量表 8B 无 tag、函数表 code_len 字节化、变长指令段 16 对齐
- 槽表 8B {addr,预留}、值段变宽紧凑(FB 布局引用清单 §8.1)
- 读取校验链(结构/SHA/型号);line1 真实拆解标注阶段 5(C5)
2026-08-25 17:35:29 +08:00

135 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# .stb 映像文件结构(V2STATOR2
编译产物 `.stb` 的**面向使用者**的结构说明。规范以 [`指令与映像.md`](指令与映像.md) 为准,本文给结构与示例。
真实 `line1.stb` 字节拆解在**阶段 5**`line1` 推演重算,C5)补充;本文示例为概念性布局。
## 概览
- 魔数 `STSC`**版本 `2`**,型号标识 `STATOR2`,全部整数小端
- 文件 = 头 + 七个段,段序:**常量表 → 函数表 → 字节码 → 槽表段 → 值段 → 元数据段 → SHA-256 尾**
- 段偏移记在头里,单调:`offset_const ≤ offset_funcs ≤ offset_code ≤ offset_slots ≤ offset_values ≤ 文件长度`
```
┌──────────────────────────────────────────────────┐
│ 头(128 字节,偏移 0,含型号标识[32]) │
├──────────────────────────────────────────────────┤
│ 常量表段 offset_const .. offset_funcs │
├──────────────────────────────────────────────────┤
│ 函数表段 offset_funcs .. offset_code │
├──────────────────────────────────────────────────┤
│ 字节码段 offset_code .. offset_slots16 对齐)│
├──────────────────────────────────────────────────┤
│ 槽表段 offset_slots .. offset_values │
├──────────────────────────────────────────────────┤
│ 值段 offset_values .. offset_meta(或文件尾)│
├──────────────────────────────────────────────────┤
│ 元数据段 offset_meta v1 = 0,空段) │
├──────────────────────────────────────────────────┤
│ SHA-256 文件尾(32 字节,对文件尾之前全部内容) │
└──────────────────────────────────────────────────┘
```
## 头(128 字节,16 对齐)
| 偏移 | 宽 | 字段 | 说明 |
|---|---|---|---|
| 0 | 4 | 魔数 `STSC` | 不变(V1 沿用) |
| 4 | 4 | 版本 `2` | V1 = 1 |
| 8 | 4 | `cycle_limit` | 每周期指令数上限 |
| 12 | 4 | `dt_ms` | 周期时长(毫秒,定时器推进步长) |
| 16 | 8 | 工程哈希(FNV-1a 64) | 源文件路径排序后对内容计算 |
| 24 | 4 | 入口 `entry_fn_id` | MAIN 函数表行下标 |
| 28 | 4 | 全局槽数 `n_globals` | 槽表内全局块条目数 |
| 32/36/40 | 4×3 | `n_i` / `n_q` / `n_m` | **保留恒 0**(V1 遗产,兼容 + 将来语义) |
| 44 | 4 | 常量数 `n_consts` | 常量表条目数 |
| 48 | 4 | 函数数 `n_funcs` | 函数表行数 |
| 52/56/60 | 4×3 | `offset_const` / `offset_funcs` / `offset_code` | 段偏移 |
| 64 | 4 | `offset_slots` | 槽表段偏移 |
| 68 | 4 | `offset_values` | 值段偏移(**16 对齐** |
| 72 | 32 | **型号标识**(定长 ASCII 含版本,补 `'\0'` | `"STATOR2"`name + version=2 |
| 104 | 4 | `n_slots` | 槽表条目数(= n_globals + FB 实例/结构体字段槽数) |
| 108 | 4 | `values_size` | 值段字节数 |
| 112 | 4 | `offset_meta` | 元数据段偏移(**v1 = 0** = 空段) |
| 116 | 4 | `max_stack` | 栈区字节数(编译期调用图最坏路径) |
| 120 | 8 | 预留 | 未来扩展 |
## 常量表段(`offset_const` 起)
一行 **8 字节**`[value:u64]`(原始位模式,**无 tag**——类型由 LOADK 指令的 func 位段解释)。
- 按位模式去重(同值多类型复用:`5` 可被 func=INT 与 func=REAL 的 LOADK 引用)
- `const_id` = 行下标(u32IMM 形态 imm32 字段)
## 函数表段(`offset_funcs` 起)
一行 12 字节:`[nregs:u32][code_offset:u32][code_len:u32]`
- **行下标即 `fn_id`**`code_offset` 相对字节码段起点(**字节**);`code_len` 为**字节数**(变长指令,字节单位)
- 入口 = 头 `entry_fn_id` 指向的行
- `nregs` = 本函数帧寄存器数(帧分配 = nregs×8 + 帧头 12Bmax_stack 由编译期按调用图算)
## 字节码段(`offset_code` 起)
**变长指令 4/8/16/32B**,段起点 16 对齐。指令字:
```text
字节 0 字节 1
[长度前缀+形态分区 | op] [func:4 | 空:4]
```
- 形态(前缀直推):`11`=RR、`10`=NONE、`011`=RRR、`010 000..101`=IMM/SLOT/JMP/JC/CALL/CAL、`0010`=SLOT+off、`0011`=IMM64、`0001`=预留
- 编码明细(位号/操作数区/uses_*)见 [`指令编码.md`](指令编码.md)、清单见 [`指令集清单.md`](指令集清单.md)
- 跳转偏移 off32 **字节单位,相对下一条**(目标 = 当前指令地址 + 指令长 + off)
- 调用约定:结果 r0、参数 r1..r7、变量与临时 r8 起;CALL/RET 复制 r0..r7 全宽
## 槽表段(`offset_slots` 起)
一行 **8 字节**`[addr:u32][预留:u32]`(addr = 值段内字节偏移,指向变量/FB 实例起始)。
- **行下标即槽号**slot u32);`n_slots`
- 槽序:全局块(声明序,`n_globals` 个)→ FB 实例块(POU 收集序、实例声明序)
## 值段(`offset_values` 起)
**变宽紧凑布局**(对齐 1/2/4/8B,编译器保证;段起点 16 对齐):
- 变量按类型占宽:BOOL 1B、INT 2B、DINT/REAL 4B、TIME/LREAL 8B…(func 宽度表)
- 变量初值、FB 实例字段初值(0)写于此;运行时拷入工作副本,文件只读
- 字段访问:`LOAD/STORE rd, slot, off32`——addr = 槽表[slot].addr + off(结构体/FB 共享体统一)
FB 实例布局(字段偏移/大小,对齐规则)见 [`指令集清单.md`](指令集清单.md) §8.1,例:
| FB | 布局(偏移) | 大小 |
|---|---|---|
| TON | in=0、pt=8、q=16、et=24 | 32B |
| CTU | cu=0、r=1、pv=2、q=4、cv=6 | 8B |
| DCTU | cu=0、r=1、pad 2..3、pv=4、q=8、pad 9..11、cv=12 | 16B |
## 元数据段(`offset_meta` 起)
v1 为空段(`offset_meta = 0`)。将来承载结构体/字符串/数组的类型描述表(字段表),schema 延后(U12)。
## SHA-256 文件尾(32 字节)
文件尾追加 32 字节 SHA-256:**对文件尾之前全部内容计算**。compiler 写侧与 vm 读侧**各自实现**一份。执行器校验不通过 → 直接拒绝。
## 读取校验链(vm 读侧)
1. **结构校验**:魔数/版本/头大小/段偏移单调且在 SHA 前/常量表·函数表尺寸一致/代码段 16 对齐/入口 fn_id 范围
2. **SHA-256**:完整性(防篡改)
3. **型号匹配**:头内 32 字节与 `"STATOR2"` 补零逐字节比对
任一不符 → `Machine::create` 拒绝,不创建机器。
## 与 sidecar / 执行器的关系
- `<name>.stb` + `<name>.runtime.toml`sidecar`[[io.input]]`/`[[io.output]]`var → 槽号 → channel/bit
- I/O 绑定**不进映像**;绑定粒度 `slot = 槽号`(指向槽表条目),channel/bit 语义不变
- executor 按 sidecar 采样 I / 写回 Q`dt_ms`/`cycle_limit` 从映像头取;`max_stack` 供 VM 预分配栈区
## 用工具验证
- `ctest``isa_roundtrip`(编解码)、`vm_cycles`(型号/SHA 拒绝)、`machine_config`V2 schema 强校验)
- `STCompiler x.stb --disasm --machine machine.toml`:显示 `model=STATOR2``sha=ok|BAD`
- 阶段 5 后:`xxd line1.stb` 对照本文逐段核对(C5 line1 推演重算)