code wiki / _hdl_build / nx_emu_x86_cf_test.nx
nx_emu_x86_cf_test.nx source
↩ module page · 83 lines · 5147 B
1// nx_emu_x86_cf_test.nx -- x86 full-system ladder R2: CONTROL FLOW. A self-contained x86-64
2// interpreter that adds flags (ZF/SF) + cmp + conditional/uncond jumps to the R1 straight-line set,
3// so it executes real LOOPS. KAT: an authored x86 loop computes sum(1..10)=55 (register-only, no
4// memory yet). Kept separate so the foundational nx_emu_x86 stays untouched (Rule 3/19).
5// HONEST SCOPE: control flow only; memory load/store (R3), modes (R5), devices (R7), boot (R8+) are
6// later rungs. No hardware writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL
7import "nx_syscalls_x86_64.nx"
8
9func cf_put_b(c: *u8, o: i64, b: i64) -> i64 { c[o]=(b & 0xff) as u8; return o+1 }
10func cf_put_i32(c: *u8, o: i64, v: i64) -> i64 { c[o]=(v&0xff) as u8; c[o+1]=((v>>8)&0xff) as u8; c[o+2]=((v>>16)&0xff) as u8; c[o+3]=((v>>24)&0xff) as u8; return o+4 }
11func cf_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
12func cf_num(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
13
14func cf_i32(code: *u8, off: i64) -> i64 {
15 var v: i64 = (code[off] as i64) | ((code[off+1] as i64) << 8) | ((code[off+2] as i64) << 16) | ((code[off+3] as i64) << 24)
16 if (v & 0x80000000) != 0 { v = v - (1 << 32) }
17 return v
18}
19
20// the R2 interpreter: R1 ops + ZF/SF + cmp(48 39) + jmp(EB) + je(74) + jne(75). FLAT decode.
21func emu_x86_run_cf(code: *u8, len: i64) -> i64 {
22 let reg: *i64 = sys_mmap(8 * 16) as *i64
23 var pc: i64 = 0
24 var zf: i64 = 0
25 var sf: i64 = 0
26 while pc < len {
27 let b: i64 = code[pc] as i64
28 var h: i64 = 0
29 if b == 0x0F {
30 if (code[pc+1] as i64) == 0x05 {
31 if reg[0] == 60 { return reg[7] & 0xff }
32 if reg[0] == 1 { sys_write(reg[7], ((code as i64) + reg[6]) as *u8, reg[2]) }
33 pc = pc + 2; h = 1
34 } else { return 0 - 1 }
35 }
36 if h == 0 { if b == 0xEB { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } pc = pc + 2 + r; h = 1 } }
37 if h == 0 { if b == 0x74 { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } if zf==1 { pc=pc+2+r } else { pc=pc+2 } h = 1 } }
38 if h == 0 { if b == 0x75 { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } if zf==0 { pc=pc+2+r } else { pc=pc+2 } h = 1 } }
39 if h == 0 { if b == 0x48 {
40 let op: i64 = code[pc+1] as i64
41 if op == 0xC7 { reg[(code[pc+2] as i64) & 7] = cf_i32(code, pc+3); pc = pc + 7; h = 1 }
42 if op == 0x89 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
43 if op == 0xC1 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] << (code[pc+3] as i64); pc = pc + 4; h = 1 }
44 if op == 0x01 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] + reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
45 if op == 0x29 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] - reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
46 if op == 0x39 { let m: i64=code[pc+2] as i64; let t: i64 = reg[m & 7] - reg[(m>>3) & 7]; if t==0 { zf=1 } else { zf=0 } if t<0 { sf=1 } else { sf=0 } pc = pc + 3; h = 1 }
47 } }
48 if h == 0 { return 0 - 3 }
49 }
50 return 0 - 4
51}
52
53func main() -> i64 {
54 cf_puts("x86 full-system ladder R2: CONTROL FLOW (cmp + jne loop)\n" as *u8)
55 let c: *u8 = sys_mmap(256)
56 var o: i64 = 0
57 // mov rax,0 ; mov rcx,10 ; mov rdx,1 ; mov rbx,0
58 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0xC7); o=cf_put_b(c,o,0xC0); o=cf_put_i32(c,o,0)
59 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0xC7); o=cf_put_b(c,o,0xC1); o=cf_put_i32(c,o,10)
60 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0xC7); o=cf_put_b(c,o,0xC2); o=cf_put_i32(c,o,1)
61 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0xC7); o=cf_put_b(c,o,0xC3); o=cf_put_i32(c,o,0)
62 let loop_off: i64 = o
63 // add rax,rcx (48 01 C8) ; sub rcx,rdx (48 29 D1) ; cmp rcx,rbx (48 39 D9)
64 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0x01); o=cf_put_b(c,o,0xC8)
65 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0x29); o=cf_put_b(c,o,0xD1)
66 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0x39); o=cf_put_b(c,o,0xD9)
67 // jne loop (75 rel8)
68 o=cf_put_b(c,o,0x75)
69 let after_jne: i64 = o + 1
70 let rel: i64 = loop_off - after_jne
71 var relb: i64 = rel
72 if relb < 0 { relb = relb + 256 }
73 o=cf_put_b(c,o,relb)
74 // mov rdi,rax (48 89 C7) ; mov rax,60 ; syscall
75 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0x89); o=cf_put_b(c,o,0xC7)
76 o=cf_put_b(c,o,0x48); o=cf_put_b(c,o,0xC7); o=cf_put_b(c,o,0xC0); o=cf_put_i32(c,o,60)
77 o=cf_put_b(c,o,0x0F); o=cf_put_b(c,o,0x05)
78
79 let rc: i64 = emu_x86_run_cf(c, o)
80 cf_puts(" authored x86 loop sum(1..10), emu result = " as *u8); cf_num(rc); cf_puts(" (want 55)\n" as *u8)
81 if rc == 55 { cf_puts("X86-CF verdict=GREEN (control flow: the sovereign x86 emu runs real loops; R3 memory next)\n" as *u8); sys_exit(0); return 0 }
82 cf_puts("X86-CF verdict=RED\n" as *u8); sys_exit(1); return 1
83}