用例反汇编对照(源码 ↔ 指令验证)
状态:13 个正例全部对照通过(2026-08-26)。方法:STCompiler 编译 → --dump-map
取变量/槽映射 → --disasm 取指令序列 → 逐条对照源码语义。
每用例记录「源码语句 ↔ 指令序列 ↔ 结论」;完整输出见 build/audit/(临时)。
01_empty_main:最小映像
02_bool_assign:常量表 + BOOL 字面量
| 源码 |
指令 |
结论 |
| a := TRUE |
LOADK.U8 r8, 0(常量[0]=1) |
✓ |
| b := FALSE |
LOADK.U8 r9, 1(常量[1]=0) |
✓ |
常量表 8B 无 tag、BOOL func=U8 ✓
03_short_circuit:短路 AND/OR
| 源码 |
指令 |
结论 |
| x := a AND b |
MOVE r10,r8 / JF r10,+8 / MOVE r11,r9 / MOVE r10,r11 |
✓ 短路跳过 rhs |
| x := a OR b |
MOVE r10,r8 / JT r10,+8 / ... |
✓ |
04_if_elsif_else:分支跳转
| 源码 |
指令 |
结论 |
| IF sel=0 THEN out:=10 |
MOVE/LOADK(0)/CMP_EQ.I16/JF +16/LOADK(10)/JMP +52 |
✓ |
| ELSIF sel=1 THEN out:=20 |
MOVE/LOADK(1)/CMP_EQ/JF/LOADK(20)/JMP +8 |
✓ |
| ELSE out:=30 |
LOADK(30) |
✓ |
跳转回填、常量正确 ✓
05_while_normal:WHILE 回填
| 源码 |
指令 |
结论 |
| n := 0 |
LOADK.I16 r8, 0 |
✓ |
| WHILE n<10 |
MOVE/LOADK(10)/CMP_LT.I16/JF +28 |
✓ |
| n := n+1 |
MOVE/LOADK(1)/ADD.I16 r8 |
✓ |
| 回跳 |
JMP -56 |
✓ |
07_int_arith:算术 func
| 源码 |
指令 |
结论 |
| a := 7*6 |
LOADK(7)/LOADK(6)/MUL.I16 r8 |
✓ |
| b := a/4 |
MOVE/LOADK(4)/DIV.I16 r9 |
✓ |
| c := a-b |
MOVE/MOVE/SUB.I16 r10 |
✓ |
| eq := c>30 |
MOVE/LOADK(30)/CMP_GT.I16 |
✓ |
08_time_literal:TIME 字面量
| 源码 |
指令 |
结论 |
| t1 := T#10ms |
LOADK.I64 r8, 0(常量 10) |
✓ |
| t2 := T#1s250ms |
LOADK.I64 r9, 1(常量 1250) |
✓ |
09_gvl_external:全局 + 初值
| 项 |
值 |
结论 |
| G1 槽 |
slot=0 off=0 type=int func=3 |
✓ |
| G1 初值 |
值段 05 00(5 小端) |
✓ |
| x := G1 |
LOAD.I16 r8, s0 |
✓ |
13_function_call:调用约定 + max_stack
| 源码 |
指令 |
结论 |
| Add: a+b |
MOVE r8,r1 / MOVE r9,r2 / ADD.I16 r0 |
✓ r0 结果 |
| x := Add(3,4) |
LOADK(3)/LOADK(4)/MOVE r1/MOVE r2/CALL 0/MOVE r8,r0 |
✓ 实参 r1..r7 |
| max_stack |
192 = (12+11×8) + (12+10×8) |
✓ 编译期 DAG |
| 映射 |
add: a=r1 b=r2 result=r0;main: x=r8 |
✓ |
15_fb_instance:用户 FB 共享体(函数化)
| 源码 |
指令 |
结论 |
| starter(start:=TRUE,...) |
LOADK(TRUE)/STORE_OFF r9,s0,0;LOADK(FALSE)/STORE_OFF r10,s0,1 → LOADK.U32 r1,1 → CALL 0 |
✓ 实参绝对槽 + r1 实例指针 |
| Q := start AND NOT stop |
fn0(共享体):LOAD_PTR.U8 r8,r1,0 / JF / LOAD_PTR.U8 r10,r1,1 / NOT / MOVE / STORE_PTR.U8 r8,r1,2 |
✓ 基址寻址+短路 |
| q := starter.Q |
LOAD_OFF r8, s0, 2 |
✓ 输出读绝对槽 |
值段 3B、映射 start@0 stop@1 q@2 ✓;fn0 单函数体服务所有实例 ✓
17_ton:内建 TON
| 源码 |
指令 |
结论 |
| t(in:=TRUE, pt:=T#30ms) |
STORE_OFF.U8 s0,0;STORE_OFF.I64 s0,8 |
✓ pt=TIME→I64 |
| 调用 |
CAL.TON s0 |
✓ fb 名显示 |
| q := t.Q |
LOAD_OFF.U8 s0,16 |
✓ 偏移 16 |
值段 32B(in@0/pt@8/q@16/et@24)✓
18_tof_ctu:双实例 + 字段偏移
| 源码 |
指令 |
结论 |
| tf(in:=FALSE, pt:=T#20ms) |
STORE_OFF s0,0/8;CAL.TOF s0;LOAD_OFF s0,16 |
✓ |
| c(cu:=TRUE,r:=FALSE,pv:=3) |
STORE_OFF s1,0/1;STORE_OFF.I16 s1,2;CAL.CTU s1 |
✓ pv=INT 2B |
| q2 := c.Q / cnt := c.CV |
LOAD_OFF.U8 s1,4;LOAD_OFF.I16 s1,6 |
✓ q@4 cv@6 |
槽表 2 条(addr 0/32)、值段 40B ✓
20_line1:全链路
| 源码 |
指令 |
结论 |
| starter(start:=I0_0, stop:=I0_1) |
LOAD.U8 r8,s1 → STORE_OFF s4,0;LOAD.U8 r9,s2 → STORE_OFF s4,1 → LOADK.U32 r1 → CALL 0 |
✓ I 读 + 共享体调用 |
| Q := start AND NOT stop AND NOT EmergencyStop |
fn0:LOAD_PTR r1,0/JF/LOAD_PTR r1,1/NOT/MOVE/JF/LOAD s0(急停)/NOT/MOVE/STORE_PTR r1,2 |
✓ 基址+双短路+全局 |
| Q0_0 := starter.Q |
LOAD_OFF s4,2 / STORE.U8 r8,s3 |
✓ Q 写 |
槽表 5 条(addr 0..4)、值段 7B ✓
结构自检(stbcheck,13 用例)
寄存器越界 / func 非法 / 跳转越界 / 槽号越界 / 指令长度越界:全部通过。
结论
- 编译器生成正确性:13 正例全部对照通过
- 结构自检:全部通过
- 已知缺陷(已修,阶段5-1):LREAL 字面量按目标 func 装载(LREAL → LOADK.F64,REAL → LOADK.F32);实测位模式 0x3FC00000(float 1.5)/ 0x4004000000000000(double 2.5)精确