code wiki / _hdl_build / nx_emu_x86_mem_test.nx
nx_emu_x86_mem_test.nx source
↩ module page · 80 lines · 5390 B
1// nx_emu_x86_mem_test.nx -- x86 full-system ladder R3: MEMORY. Extends the R2 control-flow interp
2// with a RAM region + 64-bit load/store via ModRM mod=00 base-register indirect:
3// 48 89 /r (mod=00) -> mov [base], r64 (store)
4// 48 8B /r (mod=00) -> mov r64, [base] (load)
5// (mod=11 stays register-register as before.) KAT: store 42 to RAM, clobber the reg, load it back,
6// exit = the loaded value. HONEST SCOPE: base-register indirect only (no SIB/disp yet); modes
7// (R5)/devices (R7)/boot (R8+) later. No hardware writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL
8import "nx_syscalls_x86_64.nx"
9
10func mb_put_b(c: *u8, o: i64, b: i64) -> i64 { c[o]=(b & 0xff) as u8; return o+1 }
11func mb_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 }
12func mb_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
13func mb_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 }
14
15func mb_i32(code: *u8, off: i64) -> i64 {
16 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)
17 if (v & 0x80000000) != 0 { v = v - (1 << 32) }
18 return v
19}
20func mb_st64(mem: *u8, addr: i64, v: i64) -> i64 { var i: i64=0; while i<8 { mem[addr+i]=((v>>(i*8)) & 0xff) as u8; i=i+1 } return 0 }
21func mb_ld64(mem: *u8, addr: i64) -> i64 { var v: i64=0; var i: i64=0; while i<8 { v = v | ((mem[addr+i] as i64) << (i*8)); i=i+1 } return v }
22
23func emu_x86_run_mem(code: *u8, len: i64, mem: *u8) -> i64 {
24 let reg: *i64 = sys_mmap(8 * 16) as *i64
25 var pc: i64 = 0
26 var zf: i64 = 0
27 var sf: i64 = 0
28 while pc < len {
29 let b: i64 = code[pc] as i64
30 var h: i64 = 0
31 if b == 0x0F {
32 if (code[pc+1] as i64) == 0x05 {
33 if reg[0] == 60 { return reg[7] & 0xff }
34 if reg[0] == 1 { sys_write(reg[7], ((code as i64) + reg[6]) as *u8, reg[2]) }
35 pc = pc + 2; h = 1
36 } else { return 0 - 1 }
37 }
38 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 } }
39 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 } }
40 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 } }
41 if h == 0 { if b == 0x48 {
42 let op: i64 = code[pc+1] as i64
43 if op == 0xC7 { reg[(code[pc+2] as i64) & 7] = mb_i32(code, pc+3); pc = pc + 7; h = 1 }
44 if op == 0x89 { let m: i64=code[pc+2] as i64; let md: i64=(m>>6)&3; if md==3 { reg[m & 7] = reg[(m>>3) & 7] } else { mb_st64(mem, reg[m & 7], reg[(m>>3) & 7]) } pc = pc + 3; h = 1 }
45 if op == 0x8B { let m: i64=code[pc+2] as i64; let md: i64=(m>>6)&3; if md==3 { reg[(m>>3) & 7] = reg[m & 7] } else { reg[(m>>3) & 7] = mb_ld64(mem, reg[m & 7]) } pc = pc + 3; h = 1 }
46 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 }
47 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 }
48 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 }
49 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 }
50 } }
51 if h == 0 { return 0 - 3 }
52 }
53 return 0 - 4
54}
55
56func main() -> i64 {
57 mb_puts("x86 full-system ladder R3: MEMORY (store 42 -> clobber -> load back)\n" as *u8)
58 let c: *u8 = sys_mmap(256)
59 let mem: *u8 = sys_mmap(65536)
60 var o: i64 = 0
61 // mov rbx, 100 (RAM address)
62 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0xC7); o=mb_put_b(c,o,0xC3); o=mb_put_i32(c,o,100)
63 // mov rax, 42
64 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0xC7); o=mb_put_b(c,o,0xC0); o=mb_put_i32(c,o,42)
65 // mov [rbx], rax (48 89 03: mod=00 reg=rax rm=rbx)
66 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0x89); o=mb_put_b(c,o,0x03)
67 // mov rcx, 7 (clobber)
68 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0xC7); o=mb_put_b(c,o,0xC1); o=mb_put_i32(c,o,7)
69 // mov rcx, [rbx] (48 8B 0B: mod=00 reg=rcx rm=rbx) -- load back
70 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0x8B); o=mb_put_b(c,o,0x0B)
71 // mov rdi, rcx ; mov rax,60 ; syscall
72 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0x89); o=mb_put_b(c,o,0xCF)
73 o=mb_put_b(c,o,0x48); o=mb_put_b(c,o,0xC7); o=mb_put_b(c,o,0xC0); o=mb_put_i32(c,o,60)
74 o=mb_put_b(c,o,0x0F); o=mb_put_b(c,o,0x05)
75
76 let rc: i64 = emu_x86_run_mem(c, o, mem)
77 mb_puts(" stored 42 to RAM[100], reloaded after clobber, emu result = " as *u8); mb_num(rc); mb_puts(" (want 42)\n" as *u8)
78 if rc == 42 { mb_puts("X86-MEM verdict=GREEN (memory load/store on the sovereign x86 emu; R4 kernel-subset ISA next)\n" as *u8); sys_exit(0); return 0 }
79 mb_puts("X86-MEM verdict=RED\n" as *u8); sys_exit(1); return 1
80}