Files
Interpreter/Doc/isa/指令与映像.md
T

161 lines
4.5 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.
# 指令与映像
isa 模块规范:指令集 + 映像 + 定宽类型。不是编译器,不把 `.st` 编成映像。
`compiler` 按本文件写出字节,`vm` 只认这些字节。两边不互链。
全工程定案见 [`初步计划.md`](../初步计划.md)。**类型、指令编码、映像布局以本文为准**,不要另写一份互相打架的表。头文件实现本文,不另当规范。
```text
host → compiler → isa
host → vm → isa
```
CMake 目标:`isa``STATIC`),无依赖。公开头:`isa/include/isa/`
---
## 做 / 不做
**做**
- 操作码与 32 位指令布局
- 映像头与段(函数字节码、全局 / FB 槽、工程哈希)
- `BOOL` / `INT` / `TIME` 宽度与溢出规则
- 编解码、工程哈希、一条指令的文本转储(给 host 打印)
**不做**
- toml 字段、关键字表、符号表、AST
- 扫描周期循环、I/O 采样
- 短路语义(`AND`/`OR` 指令只组合已算好的值;短路由 `compiler` 编成跳转)
指令表可作为内部 IR 的文本形态,不必当主语言。
---
## 特性
| 项 | 第一版 |
|---|---|
| `BOOL` | `uint8_t`,只允许 0/1 |
| `INT` | `int16_t`IEC `INT` |
| `TIME` | `int32_t` 毫秒;与 `INT` 不混用 |
| 整数溢出 | **饱和**(夹到 `INT` 最小/最大) |
| 字节序 | 小端 |
| 指令宽度 | 32 bit,一种主布局 |
| 寄存器 | 下标 0..255;每函数实际个数写在函数头 `nregs` |
| 跳转 | 相对 offset,单位是**指令条数**,不是字节 |
| `CALL` | 立即数 `fn_id`u16),无函数指针 |
| 映像魔数 | `STSC`,版本 `1` |
| 工程哈希 | 源文件路径排序后对内容做 FNV-1a 64(非密码学) |
| I/O 绑定 | **不进映像**;编译期把 `var` 收成槽号,channel/bit 留在 host 读 toml |
| 不做 | `REAL`、隐式宽化、独立 `stc.exe` |
---
## 类型
C++11 定宽:
- `BOOL``uint8_t`0/1
- `INT``int16_t`;加减乘除溢出饱和
- `TIME``int32_t` 毫秒
`compiler``vm` 都按同一规则,不再另选溢出策略。
---
## 指令
定宽 32 bit
```text
[ op:8 | rd:8 | a:8 | b:8 ]
```
- 三寄存器:`a`/`b``ra`/`rb``MOVE`/`NOT` 只用 `rd`+`a`
- `LOADK``a|b``const_id`u16
- `JMP` / `JT` / `JF``a|b` 为有符号相对 offset(指令条数)
- `CALL``a|b``fn_id`u16
操作码一次列全(`CMP_xx` 冻下面六种):
```text
MOVE rd, rs
LOADK rd, const_id
NOT rd, rs
AND/OR rd, ra, rb (* 已算好的值;短路用跳转 *)
ADD/SUB/MUL/DIV rd, ra, rb
CMP_EQ/NE/LT/LE/GT/GE rd, ra, rb
JMP offset
JT/JF r, offset
LOAD_I / STORE_Q / LOAD_M / STORE_M
LOAD_GLOBAL / STORE_GLOBAL
CAL_TON / CAL_TOF / CAL_CTU
CALL fn_id
RET
```
局部 / `VAR` = 固定寄存器;表达式临时值往后编号;`nregs` 写进函数头。
`I`/`Q`/`M` 走映像指令,不是通用寄存器。
FB 实例固定布局,字段偏移编译期算死。
---
## 映像
魔数 `STSC`,版本 `1`
头:
- `cycle_limit``dt_ms`
- 工程哈希
- 全局槽数、I/Q/M 槽数
- 常量表 / 函数表 / 字节码 / FB 布局的偏移
- 入口 `MAIN``fn_id`
函数表一行:`fn_id``nregs`、字节码偏移与长度。
工程哈希:收录源文件路径排序后对内容做 **FNV-1a 64**,只保证回放槽位一致,不是密码学哈希。
`[[io.input]]` / `[[io.output]]` 不进映像。
---
## 目录与 CMake
```text
isa/
CMakeLists.txt
README.md # 代码目录入口,指向本文
include/isa/
Types.hpp # 宽度、饱和、槽值表示
Op.hpp # 操作码枚举 + 助记符
Instr.hpp # 32-bit 打包/拆字段(inline
Image.hpp # 头、段、函数表/常量表/FB 布局
Encode.hpp # 编解码、哈希、反汇编一行
src/
Encode.cpp
Image.cpp
```
```cmake
add_library(isa STATIC src/Encode.cpp src/Image.cpp)
target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
```
`compiler` / `vm``target_link_libraries(... PUBLIC isa)`
---
## 实现顺序(对齐初步计划 12.0~12.1)
1. `Types.hpp`:三类型 + `sat_add` 等饱和函数(inline 即可)
2. `Op.hpp` + `Instr.hpp`:枚举与 32-bit 编解码
3. `Encode.cpp``encode` / `decode` / `disasm` 一条指令
4. `Image.hpp` + `Image.cpp`:头布局、FNV-1a、读写缓冲(先能写空映像 + 一条 `RET`
5. 测试随后在 `tests/` 加编解码往返;本阶段以头文件和库能链为准
不在本模块做:VM `switch`、toml、关键字、符号表。