实现指令编解码与反汇编,冻结 disasm 格式。

- Encode.h/Encode.cpp:encode/decode 往返 + disasm 一行文本
- 指令与映像.md 新增反汇编格式表(9 种形态 + 未知操作码)
- Op.h STORE_* 注释对齐 disasm(rs, slot 寄存器在前)
This commit is contained in:
2026-08-19 14:06:20 +08:00
parent 7c855b1618
commit eba48f852e
4 changed files with 149 additions and 3 deletions
+19
View File
@@ -107,6 +107,25 @@ RET
`I`/`Q`/`M` 走映像指令,不是通用寄存器。 `I`/`Q`/`M` 走映像指令,不是通用寄存器。
FB 实例固定布局,字段偏移编译期算死。 FB 实例固定布局,字段偏移编译期算死。
### 反汇编格式(disasm
`disasm` 输出一条指令的一行文本,格式冻结:
| 形态 | 格式 | 示例 |
|---|---|---|
| 二寄存器 | `MOVE rd, rs` / `NOT rd, rs` | `MOVE r1, r2` |
| 三寄存器 | `OP rd, ra, rb`(逻辑 / 算术 / 比较) | `ADD r1, r2, r3` |
| 常量 | `LOADK rd, imm` | `LOADK r0, 3` |
| 无条件跳转 | `JMP off` | `JMP +4` |
| 条件跳转 | `JT rd, off` / `JF rd, off` | `JT r0, -1` |
| I/Q/M/全局 | `LOAD_I rd, slot` 等;STORE 同形 `STORE_Q rs, slot` | `LOAD_I r0, 2` |
| FB 内置 | `CAL_TON instance` 等 | `CAL_TON 0` |
| 调用 | `CALL fn_id` | `CALL 1` |
| 返回 | `RET` | `RET` |
| 未知操作码 | `??? 0x<hex>` | — |
跳转偏移带符号、恒显正负号(`%+d`);寄存器一律 `r<n>`;常量/槽号/`fn_id` 无符号十进制。
--- ---
## 映像 ## 映像
+31
View File
@@ -0,0 +1,31 @@
/**
* @file Encode.h
* @brief 指令编解码与反汇编
* @author
* @date 2026-08-19
*/
#pragma once
#include <cstddef>
#include <cstdint>
#include "isa/Instr.h"
#include "isa/Op.h"
namespace isa {
// 解码后的字段视图
struct Decoded {
Op op;
uint8_t rd;
uint8_t a;
uint8_t b;
};
// 编解码往返:encode(decode(w)) == w
Instr encode(Decoded d);
Decoded decode(Instr w);
// 反汇编一行文本,写入 out,至多 cap 字节(含 '\0')。格式见 Doc/isa/指令与映像.md。
void disasm(Instr w, char* out, size_t cap);
}
+3 -3
View File
@@ -32,11 +32,11 @@ namespace isa {
JT = 16, // JT r, offset JT = 16, // JT r, offset
JF = 17, // JF r, offset JF = 17, // JF r, offset
LOAD_I = 18, // LOAD_I rd, slot LOAD_I = 18, // LOAD_I rd, slot
STORE_Q = 19, // STORE_Q slot, rs STORE_Q = 19, // STORE_Q rs, slot
LOAD_M = 20, // LOAD_M rd, slot LOAD_M = 20, // LOAD_M rd, slot
STORE_M = 21, // STORE_M slot, rs STORE_M = 21, // STORE_M rs, slot
LOAD_GLOBAL = 22, // LOAD_GLOBAL rd, slot LOAD_GLOBAL = 22, // LOAD_GLOBAL rd, slot
STORE_GLOBAL = 23, // STORE_GLOBAL slot, rs STORE_GLOBAL = 23, // STORE_GLOBAL rs, slot
CAL_TON = 24, // CAL_TON instance_slot CAL_TON = 24, // CAL_TON instance_slot
CAL_TOF = 25, // CAL_TOF instance_slot CAL_TOF = 25, // CAL_TOF instance_slot
CAL_CTU = 26, // CAL_CTU instance_slot CAL_CTU = 26, // CAL_CTU instance_slot
+96
View File
@@ -0,0 +1,96 @@
/**
* @file Encode.cpp
* @brief 指令编解码与反汇编
* @author
* @date 2026-08-19
*/
#include "isa/Encode.h"
#include <cstdio>
namespace isa {
Instr encode(Decoded d) {
return pack(d.op, d.rd, d.a, d.b);
}
Decoded decode(Instr w) {
Decoded d;
d.op = op(w);
d.rd = rd(w);
d.a = a(w);
d.b = b(w);
return d;
}
void disasm(Instr w, char* out, size_t cap) {
if (cap == 0) {
return;
}
out[0] = '\0';
const Op o = op(w);
const int idx = static_cast<int>(o);
if (idx < 0 || idx >= kOpCount) {
snprintf(out, cap, "??? 0x%08x", static_cast<unsigned>(w));
return;
}
const char* m = mnemonic(o);
switch (o) {
case Op::MOVE:
case Op::NOT:
snprintf(out, cap, "%s r%u, r%u", m,
static_cast<unsigned>(rd(w)), static_cast<unsigned>(a(w)));
break;
case Op::AND:
case Op::OR:
case Op::ADD:
case Op::SUB:
case Op::MUL:
case Op::DIV:
case Op::CMP_EQ:
case Op::CMP_NE:
case Op::CMP_LT:
case Op::CMP_LE:
case Op::CMP_GT:
case Op::CMP_GE:
snprintf(out, cap, "%s r%u, r%u, r%u", m,
static_cast<unsigned>(rd(w)), static_cast<unsigned>(a(w)),
static_cast<unsigned>(b(w)));
break;
case Op::LOADK:
snprintf(out, cap, "%s r%u, %u", m,
static_cast<unsigned>(rd(w)), static_cast<unsigned>(imm16(w)));
break;
case Op::JMP:
snprintf(out, cap, "%s %+d", m, static_cast<int>(off16(w)));
break;
case Op::JT:
case Op::JF:
snprintf(out, cap, "%s r%u, %+d", m,
static_cast<unsigned>(rd(w)), static_cast<int>(off16(w)));
break;
case Op::LOAD_I:
case Op::STORE_Q:
case Op::LOAD_M:
case Op::STORE_M:
case Op::LOAD_GLOBAL:
case Op::STORE_GLOBAL:
snprintf(out, cap, "%s r%u, %u", m,
static_cast<unsigned>(rd(w)), static_cast<unsigned>(imm16(w)));
break;
case Op::CAL_TON:
case Op::CAL_TOF:
case Op::CAL_CTU:
case Op::CALL:
snprintf(out, cap, "%s %u", m, static_cast<unsigned>(imm16(w)));
break;
case Op::RET:
snprintf(out, cap, "%s", m);
break;
}
}
} // namespace isa