Files
Interpreter/Doc/isa/stb文件格式.md
T
Admin 26256a36b9 扩充内置功能块为 8 个:TON/TOF/TP/CTU/CTD/CTUD/R_TRIG/F_TRIG。
- isa:CAL_* 操作码连续占 24..31(CALL/RET 后移为 32/33,kOpCount=34);disasm 支持 5 个新操作码
- 词法/语法/链接:新 8 个关键字与冻结布局(TP=in/pt/q/et、CTD=cd/ld/pv/q/cv、
  CTUD=cu/cd/r/lu/pv/qu/qd/cv、R_TRIG/F_TRIG=clk/q)
- VM:do_cal 全 8 个语义(TP 脉冲、CTD 递减、CTUD 双向+装载、R_TRIG 上升沿、F_TRIG 下降沿);
  edge_prev_ 每槽 2 字节存边沿上次输入;exec_one 分发补 5 个新操作码
- 验证:TP 30ms 脉冲 2 周期、CTD 装载+递减到 q=1、CTUD cu/cd 双向、R/F_TRIG 交替;
  ctest 11/11 全绿
- 文档:指令与映像/词法/初步计划/符号表与链接/指令执行/扫描周期/使用说明 同步
2026-08-21 20:38:27 +08:00

5.8 KiB
Raw Blame History

.stb 映像文件结构

编译产物 .stb面向使用者的结构说明。规范以 指令与映像.md 为准,本文用 line1.stb224 字节)做真实拆解。

概览

  • 魔数 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_datav1 为空)│
├──────────────────────────────────────────────────┤
│ 数据段    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 1MAIN
28 4 全局槽数 n_globals 4
32 4 I 槽数 n_i 0v1 不拆)
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]tag0=BOOL、1=INT、2=TIME。

line1 无字面量常量 → 段为空(offset_const == offset_funcs)。

函数表段(offset_funcs 起)

一行 12 字节:[nregs:u32][code_offset:u32][code_len:u32]

  • 行下标即 fn_idcode_offset 相对字节码段起点(字节);code_len指令条数
  • 入口 = 头的 entry_fn_id 指向的行

line12 行):

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
  • CALLfn_id = 函数表行下标
  • 调用约定:结果 r0、参数 r1..r7、变量与临时 r8 起

line1 MAIN 前 5 条(0x60 起,slot 为 8 字节定宽槽号):

偏移 字节 反汇编 含义
0x64 12 08 01 00 LOAD_I r8, 1 I0_0io.input 绑定 → LOAD_I,槽 1
0x68 17 08 04 00 STORE_GLOBAL r8, 4 starter.start(槽 4)← I0_0
0x6C 16 09 02 00 LOAD_GLOBAL r9, 2 I0_1(槽 2
0x70 17 09 05 00 STORE_GLOBAL r9, 5 starter.stop(槽 5)← I0_1
0x74 16 08 04 00 LOAD_GLOBAL r8, 4 内联体:读 starter.start(槽 4

FB 布局段(offset_fb 起)

v1 为空(用户 FB 内联展开,字段偏移已算进数据段;内建 8 个 FB 布局冻结在编译器中(12.11 扩充))。行格式约定:[field_count:u32][field_count × (tag:u32, offset:u32)]offset 相对实例基址。

数据段(offset_data 起)

每槽 8 字节定宽12.9 方案 a):BOOL 用低 1 字节、INT 用低 2 字节(小端)、TIME 全 8 字节。指令 slot 操作数即槽号,数据偏移 = 槽号 × 8。

槽序:全局块n_globals 个,声明序)→ FB 实例块(POU 收集序、实例声明序,每字段一槽)。

line1 数据段(56 字节 = 7 槽 × 8B,0xA8 起):

槽号 偏移 内容
0 0xA8 EmergencyStopBOOL,初值 0
1 0xB0 I0_0BOOL
2 0xB8 I0_1BOOL
3 0xC0 Q0_0BOOL
4 0xC8 starter.startBOOL
5 0xD0 starter.stopBOOL
6 0xD8 starter.qBOOL

用工具验证

  • ctestisa_roundtrip / codegen_slice1 覆盖编解码往返与映像校验
  • isa::ImageView 提供只读视图(校验魔数/版本/段边界/入口 fn_id)
  • 手工检查:xxd line1.stb 对照上表逐段核对

与执行器的关系

BytecodeExecutor12.9/12.10 实现)只读本格式:头(cycle_limit/dt_ms)、函数表(帧 nregs + 代码定位)、数据段(全局 + FB 实例状态)。I/O 绑定不在映像里,在 sidecar <name>.runtime.tomlvar → 槽号 → channel/bit)。