12.9 步骤 0:数据段改 8 字节定宽槽(方案 a)。
- 指令与映像.md / 寄存器码.md:slot 语义 = 槽号(数据偏移 = 槽号 × 8),取消变宽对齐与 global_offset 映射 - Codegen.cpp:删除 width_of/align_up/global_offsets_;layout_data/layout_fb_instances 按槽号布局(字段 = 槽序号) - stb文件格式.md:line1 真实字节更新(224B、56B 数据段、starter 槽 4/5/6) - codegen_test:断言更新(槽号化 + 数据区字节数),189 断言 9/9 全绿
This commit is contained in:
+19
-16
@@ -1,6 +1,6 @@
|
||||
# .stb 映像文件结构
|
||||
|
||||
编译产物 `.stb` 的**面向使用者**的结构说明。规范以 [`指令与映像.md`](指令与映像.md) 为准,本文用 `line1.stb`(184 字节)做真实拆解。
|
||||
编译产物 `.stb` 的**面向使用者**的结构说明。规范以 [`指令与映像.md`](指令与映像.md) 为准,本文用 `line1.stb`(224 字节)做真实拆解。
|
||||
|
||||
## 概览
|
||||
|
||||
@@ -74,15 +74,15 @@ line1(2 行):
|
||||
- `CALL` 的 `fn_id` = 函数表行下标
|
||||
- 调用约定:结果 r0、参数 r1..r7、变量与临时 r8 起
|
||||
|
||||
line1 `MAIN` 前 5 条(`0x60` 起):
|
||||
line1 `MAIN` 前 5 条(`0x60` 起,slot 为 8 字节定宽槽号):
|
||||
|
||||
| 偏移 | 字节 | 反汇编 | 含义 |
|
||||
|---|---|---|---|
|
||||
| 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 |
|
||||
| 0x64 | `12 08 01 00` | `LOAD_I r8, 1` | I0_0(io.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` 起)
|
||||
|
||||
@@ -90,18 +90,21 @@ v1 为空(用户 FB 内联展开,字段偏移已算进数据段;内建 TON
|
||||
|
||||
## 数据段(`offset_data` 起)
|
||||
|
||||
**全局块**(`n_globals` 个,声明序)→ **FB 实例块**(按 POU 收集序、实例声明序,块间 8 字节对齐)。
|
||||
**每槽 8 字节定宽**(12.9 方案 a):`BOOL` 用低 1 字节、`INT` 用低 2 字节(小端)、`TIME` 全 8 字节。指令 `slot` 操作数即**槽号**,数据偏移 = 槽号 × 8。
|
||||
|
||||
槽宽与对齐:`BOOL` 1 字节 / `INT` 2 字节 / `TIME` 8 字节,每个槽起点对齐自身宽度。
|
||||
槽序:**全局块**(`n_globals` 个,声明序)→ **FB 实例块**(POU 收集序、实例声明序,每字段一槽)。
|
||||
|
||||
line1 数据段(16 字节,`0xA8` 起):
|
||||
line1 数据段(56 字节 = 7 槽 × 8B,`0xA8` 起):
|
||||
|
||||
| 偏移 | 内容 |
|
||||
|---|---|
|
||||
| 0xA8..0xAB | 全局:EmergencyStop、I0_0、I0_1、Q0_0(BOOL,初值 0) |
|
||||
| 0xAC..0xAF | 填充(实例块 8 对齐) |
|
||||
| 0xB0..0xB2 | starter 实例:start、stop、q(BOOL) |
|
||||
| 0xB3..0xB7 | 填充 |
|
||||
| 槽号 | 偏移 | 内容 |
|
||||
|---|---|---|
|
||||
| 0 | 0xA8 | EmergencyStop(BOOL,初值 0) |
|
||||
| 1 | 0xB0 | I0_0(BOOL) |
|
||||
| 2 | 0xB8 | I0_1(BOOL) |
|
||||
| 3 | 0xC0 | Q0_0(BOOL) |
|
||||
| 4 | 0xC8 | starter.start(BOOL) |
|
||||
| 5 | 0xD0 | starter.stop(BOOL) |
|
||||
| 6 | 0xD8 | starter.q(BOOL) |
|
||||
|
||||
## 用工具验证
|
||||
|
||||
|
||||
+2
-2
@@ -76,7 +76,7 @@ C++20 定宽:
|
||||
|
||||
- 有符号:`TOF` 剩余时间、两个时间点相减会出负值,免去无符号边界处理
|
||||
- 64 位:为将来 `DATE_AND_TIME`(毫秒时间戳)与 `TON` / `TOF` / `TP` 的 64 位定时器预留;毫秒量程约 2.9 亿年,扫描周期场景永不溢出
|
||||
- 代价:槽位 8 字节对齐。**槽位对齐规则**:`BOOL` 1 字节、`INT` 2 字节、`TIME` 8 字节;连续排列按类型对齐,需要时插 padding,偏移以本规则为准。
|
||||
- 代价:槽位 8 字节对齐。**槽位规则**(12.9 方案 a):每槽 8 字节定宽,`BOOL` 用低 1 字节、`INT` 用低 2 字节(小端)、`TIME` 全 8 字节;槽号 × 8 = 数据偏移,无 padding。
|
||||
|
||||
---
|
||||
|
||||
@@ -180,7 +180,7 @@ FB 实例固定布局,字段偏移编译期算死。
|
||||
|
||||
### 数据段
|
||||
|
||||
槽初值按序排:全局(`n_globals`)→ I → Q → M。槽宽与对齐:`BOOL` 1 字节 / `INT` 2 字节 / `TIME` 8 字节,每个槽起点对齐到自身宽度(需要时插 padding)。
|
||||
槽初值按序排:全局(`n_globals`,v1 不拆 I/Q/M)→ FB 实例块(每字段一槽)。**每槽 8 字节定宽**(12.9 方案 a):`BOOL` 用低 1 字节、`INT` 用低 2 字节(小端)、`TIME` 全 8 字节。指令 `slot` 操作数即**槽号**,数据偏移 = 槽号 × 8;符号表 `address` 与指令 slot 一致,无映射。
|
||||
|
||||
工程哈希:收录源文件路径排序后对内容做 **FNV-1a 64**,只保证回放槽位一致,不是密码学哈希。FNV-1a 64:basis `0xcbf29ce484222325`,prime `0x100000001b3`。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user