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}