code wiki / _hdl_build / nx_emu_x86_k.nx

nx_emu_x86_k.nx source

↩ module page · 55 lines · 3914 B

1// nx_emu_x86_k.nx -- x86 full-system ladder R4: the CONSOLIDATED kernel-subset x86-64 interpreter 2// (a reusable LIB; stops the per-rung duplication of R1-R3). Instruction set so far: 3// R1: mov imm/reg, shl, add, sub, syscall(write/exit) 4// R2: ZF/SF flags, cmp(48 39), jmp(EB), je(74), jne(75) 5// R3: 64-bit memory load/store via ModRM mod=00 base-indirect (48 89 store / 48 8B load) 6// R4: a STACK + push(50+r)/pop(58+r) + call(E8 rel32)/ret(C3) == real FUNCTION CALLS 7// Caller passes a `mem` region (RAM + stack live here; rsp = reg[4]). FLAT decode (nx_cc-friendly). 8// HONEST SCOPE: still flat 64-bit long-mode-ish execution; privilege modes (R5), IDT/paging (R6), 9// devices (R7), boot (R8+) are later rungs. No hardware writes (Rule 26). license_tier: ORIGINAL 10import "nx_syscalls_x86_64.nx" 11 12func k_i32(code: *u8, off: i64) -> i64 { 13 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) 14 if (v & 0x80000000) != 0 { v = v - (1 << 32) } 15 return v 16} 17func k_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 } 18func k_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 } 19 20func emu_x86_run_k(code: *u8, len: i64, mem: *u8) -> i64 { 21 let reg: *i64 = sys_mmap(8 * 16) as *i64 22 var pc: i64 = 0 23 var zf: i64 = 0 24 var sf: i64 = 0 25 while pc < len { 26 let b: i64 = code[pc] as i64 27 var h: i64 = 0 28 if b == 0x0F { 29 if (code[pc+1] as i64) == 0x05 { 30 if reg[0] == 60 { return reg[7] & 0xff } 31 if reg[0] == 1 { sys_write(reg[7], ((code as i64) + reg[6]) as *u8, reg[2]) } 32 pc = pc + 2; h = 1 33 } else { return 0 - 1 } 34 } 35 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 } } 36 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 } } 37 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 } } 38 if h == 0 { if b == 0xE8 { let rel: i64=k_i32(code, pc+1); reg[4]=reg[4]-8; k_st64(mem, reg[4], pc+5); pc=pc+5+rel; h = 1 } } 39 if h == 0 { if b == 0xC3 { pc = k_ld64(mem, reg[4]); reg[4]=reg[4]+8; h = 1 } } 40 if h == 0 { if b >= 0x50 { if b <= 0x57 { reg[4]=reg[4]-8; k_st64(mem, reg[4], reg[b-0x50]); pc=pc+1; h = 1 } } } 41 if h == 0 { if b >= 0x58 { if b <= 0x5F { reg[b-0x58]=k_ld64(mem, reg[4]); reg[4]=reg[4]+8; pc=pc+1; h = 1 } } } 42 if h == 0 { if b == 0x48 { 43 let op: i64 = code[pc+1] as i64 44 if op == 0xC7 { reg[(code[pc+2] as i64) & 7] = k_i32(code, pc+3); pc = pc + 7; h = 1 } 45 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 { k_st64(mem, reg[m & 7], reg[(m>>3) & 7]) } pc = pc + 3; h = 1 } 46 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] = k_ld64(mem, reg[m & 7]) } pc = pc + 3; h = 1 } 47 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 } 48 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 } 49 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 } 50 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 } 51 } } 52 if h == 0 { return 0 - 3 } 53 } 54 return 0 - 4 55}