diff --git a/Doc/isa/指令与映像.md b/Doc/isa/指令与映像.md index 63ac85a..311ea1b 100644 --- a/Doc/isa/指令与映像.md +++ b/Doc/isa/指令与映像.md @@ -107,6 +107,25 @@ RET `I`/`Q`/`M` 走映像指令,不是通用寄存器。 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` | — | + +跳转偏移带符号、恒显正负号(`%+d`);寄存器一律 `r`;常量/槽号/`fn_id` 无符号十进制。 + --- ## 映像 diff --git a/isa/include/isa/Encode.h b/isa/include/isa/Encode.h new file mode 100644 index 0000000..ea4d8ad --- /dev/null +++ b/isa/include/isa/Encode.h @@ -0,0 +1,31 @@ +/** + * @file Encode.h + * @brief 指令编解码与反汇编 + * @author + * @date 2026-08-19 + */ + +#pragma once + +#include +#include + +#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); +} diff --git a/isa/include/isa/Op.h b/isa/include/isa/Op.h index 42bc79e..e74b33e 100644 --- a/isa/include/isa/Op.h +++ b/isa/include/isa/Op.h @@ -32,11 +32,11 @@ namespace isa { JT = 16, // JT r, offset JF = 17, // JF r, offset 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 - STORE_M = 21, // STORE_M slot, rs + STORE_M = 21, // STORE_M rs, 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_TOF = 25, // CAL_TOF instance_slot CAL_CTU = 26, // CAL_CTU instance_slot diff --git a/isa/src/Encode.cpp b/isa/src/Encode.cpp index e69de29..f6f1391 100644 --- a/isa/src/Encode.cpp +++ b/isa/src/Encode.cpp @@ -0,0 +1,96 @@ +/** + * @file Encode.cpp + * @brief 指令编解码与反汇编 + * @author + * @date 2026-08-19 + */ + +#include "isa/Encode.h" + +#include + +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(o); + if (idx < 0 || idx >= kOpCount) { + snprintf(out, cap, "??? 0x%08x", static_cast(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(rd(w)), static_cast(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(rd(w)), static_cast(a(w)), + static_cast(b(w))); + break; + case Op::LOADK: + snprintf(out, cap, "%s r%u, %u", m, + static_cast(rd(w)), static_cast(imm16(w))); + break; + case Op::JMP: + snprintf(out, cap, "%s %+d", m, static_cast(off16(w))); + break; + case Op::JT: + case Op::JF: + snprintf(out, cap, "%s r%u, %+d", m, + static_cast(rd(w)), static_cast(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(rd(w)), static_cast(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(imm16(w))); + break; + case Op::RET: + snprintf(out, cap, "%s", m); + break; + } +} + +} // namespace isa