diff --git a/Doc/isa/stb文件格式.md b/Doc/isa/stb文件格式.md new file mode 100644 index 0000000..7474d44 --- /dev/null +++ b/Doc/isa/stb文件格式.md @@ -0,0 +1,114 @@ +# .stb 映像文件结构 + +编译产物 `.stb` 的**面向使用者**的结构说明。规范以 [`指令与映像.md`](指令与映像.md) 为准,本文用 `line1.stb`(184 字节)做真实拆解。 + +## 概览 + +- 魔数 `STSC`,版本 `1`,**全部整数小端** +- 文件 = 头 + 五个段,段序:**常量表 → 函数表 → 字节码 → FB 布局 → 数据** +- 段偏移记在头里;`offset_const ≤ offset_funcs ≤ offset_code ≤ offset_fb ≤ offset_data ≤ 文件长度` + +``` +┌──────────────────────────────────────────────────┐ +│ 头(72 字节,偏移 0) │ +├──────────────────────────────────────────────────┤ +│ 常量表段 offset_const .. offset_funcs │ +├──────────────────────────────────────────────────┤ +│ 函数表段 offset_funcs .. offset_code │ +├──────────────────────────────────────────────────┤ +│ 字节码段 offset_code .. offset_fb │ +├──────────────────────────────────────────────────┤ +│ FB 布局段 offset_fb .. offset_data(v1 为空)│ +├──────────────────────────────────────────────────┤ +│ 数据段 offset_data .. 文件末尾 │ +└──────────────────────────────────────────────────┘ +``` + +## 头(72 字节) + +| 偏移 | 宽 | 字段 | line1 实际值 | +|---|---|---|---| +| 0 | 4 | 魔数 `STSC` | `53 53 54 43` | +| 4 | 4 | 版本 `1` | 1 | +| 8 | 4 | `cycle_limit`(每周期指令上限) | 100000 | +| 12 | 4 | `dt_ms`(本周期 Δt) | 10 | +| 16 | 8 | 工程哈希(FNV-1a 64) | `0xc3fe4ae74ad45900` | +| 24 | 4 | 入口 `entry_fn_id` | 1(MAIN) | +| 28 | 4 | 全局槽数 `n_globals` | 4 | +| 32 | 4 | I 槽数 `n_i` | 0(v1 不拆) | +| 36 | 4 | Q 槽数 `n_q` | 0 | +| 40 | 4 | M 槽数 `n_m` | 0 | +| 44 | 4 | 常量数 `n_consts` | 0 | +| 48 | 4 | 函数数 `n_funcs` | 2 | +| 52 | 4 | `offset_const` | 72 | +| 56 | 4 | `offset_funcs` | 72 | +| 60 | 4 | `offset_code` | 96 | +| 64 | 4 | `offset_fb` | 168 | +| 68 | 4 | `offset_data` | 168 | + +## 常量表段(`offset_const` 起) + +一行 12 字节:`[tag:u32][value:u64]`;`tag`:0=BOOL、1=INT、2=TIME。 + +line1 无字面量常量 → 段为空(`offset_const == offset_funcs`)。 + +## 函数表段(`offset_funcs` 起) + +一行 12 字节:`[nregs:u32][code_offset:u32][code_len:u32]` + +- **行下标即 `fn_id`**;`code_offset` 相对字节码段起点(**字节**);`code_len` 为**指令条数** +- 入口 = 头的 `entry_fn_id` 指向的行 + +line1(2 行): + +| fn_id | nregs | code_offset | code_len | 内容 | +|---|---|---|---|---| +| 0 | 8 | 0 | 1 | `MotorStarter` 占位(内联展开,仅 RET) | +| 1 | 13 | 4 | 17 | `MAIN` | + +## 字节码段(`offset_code` 起) + +指令 4 字节一条:`[op:8 | rd:8 | a:8 | b:8]`(小端 u32)。 + +- `rd` 目的寄存器;`a|b` 视操作码为寄存器、槽号(u16)或跳转偏移(有符号 int16,**相对下一条指令**:目标 = 当前 + 1 + off) +- `CALL` 的 `fn_id` = 函数表行下标 +- 调用约定:结果 r0、参数 r1..r7、变量与临时 r8 起 + +line1 `MAIN` 前 5 条(`0x60` 起): + +| 偏移 | 字节 | 反汇编 | 含义 | +|---|---|---|---| +| 0x60 | `12 08 01 00` | `LOAD_I r8, 1` | I0_0(io.input 绑定 → LOAD_I) | +| 0x64 | `17 08 08 00` | `STORE_GLOBAL r8, 8` | starter.start ← I0_0 | +| 0x68 | `16 09 02 00` | `LOAD_GLOBAL r9, 2` | I0_1 | +| 0x6C | `17 09 09 00` | `STORE_GLOBAL r9, 9` | starter.stop ← I0_1 | +| 0x70 | `16 08 08 00` | `LOAD_GLOBAL r8, 8` | 内联体:读 starter.start | + +## FB 布局段(`offset_fb` 起) + +v1 为空(用户 FB 内联展开,字段偏移已算进数据段;内建 TON/TOF/CTU 布局冻结在编译器中)。行格式约定:`[field_count:u32][field_count × (tag:u32, offset:u32)]`,offset 相对实例基址。 + +## 数据段(`offset_data` 起) + +**全局块**(`n_globals` 个,声明序)→ **FB 实例块**(按 POU 收集序、实例声明序,块间 8 字节对齐)。 + +槽宽与对齐:`BOOL` 1 字节 / `INT` 2 字节 / `TIME` 8 字节,每个槽起点对齐自身宽度。 + +line1 数据段(16 字节,`0xA8` 起): + +| 偏移 | 内容 | +|---|---| +| 0xA8..0xAB | 全局:EmergencyStop、I0_0、I0_1、Q0_0(BOOL,初值 0) | +| 0xAC..0xAF | 填充(实例块 8 对齐) | +| 0xB0..0xB2 | starter 实例:start、stop、q(BOOL) | +| 0xB3..0xB7 | 填充 | + +## 用工具验证 + +- `ctest` 的 `isa_roundtrip` / `codegen_slice1` 覆盖编解码往返与映像校验 +- `isa::ImageView` 提供只读视图(校验魔数/版本/段边界/入口 fn_id) +- 手工检查:`xxd line1.stb` 对照上表逐段核对 + +## 与执行器的关系 + +`BytecodeExecutor`(12.9/12.10 实现)只读本格式:头(`cycle_limit`/`dt_ms`)、函数表(帧 `nregs` + 代码定位)、数据段(全局 + FB 实例状态)。I/O 绑定**不在**映像里,在 sidecar `.runtime.toml`(var → 槽号 → channel/bit)。 diff --git a/Doc/索引.md b/Doc/索引.md index 74da622..e45b0c3 100644 --- a/Doc/索引.md +++ b/Doc/索引.md @@ -7,6 +7,7 @@ doc/ 索引.md 初步计划.md isa/指令与映像.md + isa/stb文件格式.md compiler/编译管线.md compiler/STCompiler使用说明.md compiler/词法.md @@ -22,6 +23,7 @@ doc/ |---|---| | [`初步计划.md`](初步计划.md) | 全工程定案:子集 ST、toml、执行模型、第 12 节阶段 | | [`isa/指令与映像.md`](isa/指令与映像.md) | 指令、映像、定宽类型、饱和;**规范以此为准** | +| [`isa/stb文件格式.md`](isa/stb文件格式.md) | `.stb` 结构说明(用 line1 真实字节拆解) | | [`compiler/编译管线.md`](compiler/编译管线.md) | 编译器边界与管线 | | [`compiler/STCompiler使用说明.md`](compiler/STCompiler使用说明.md) | 构建、用法、工程文件、ST 子集、错误类别 | | [`compiler/词法.md`](compiler/词法.md) | 12.4 词法:关键字表、token、大小写、TIME 字面量 | diff --git a/isa/README.md b/isa/README.md index f17b372..608797c 100644 --- a/isa/README.md +++ b/isa/README.md @@ -9,7 +9,7 @@ STCompiler → compiler → isa BytecodeExecutor → vm → isa ``` -**类型、操作码、指令字、映像布局以** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。全工程阶段见 [`doc/初步计划.md`](../doc/初步计划.md) 12.0~12.1。 +**类型、操作码、指令字、映像布局以** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。`.stb` 结构面向使用者的拆解见 [`doc/isa/stb文件格式.md`](../doc/isa/stb文件格式.md)。全工程阶段见 [`doc/初步计划.md`](../doc/初步计划.md) 12.0~12.1。 公开头:`isa/include/isa/`。