code wiki / _hdl_build / nx_eng_asm_scan_min_test.nx

nx_eng_asm_scan_min_test.nx source

↩ module page · 39 lines · 1599 B

1// minimal: the ENGINEER scans real assembly and finds the live-across-call register. 2// Known answer: 1 flag, register rax. -> exit 0. 3import "nx_eng_asm_scan.nx" 4 5func mt_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 6func mt_num(v: i64) -> i64 { 7 let b: *u8 = sys_mmap(28); var m: i64 = v; var k: i64 = 0; let t: *u8 = sys_mmap(28) 8 if m == 0 { t[0] = 48; k = 1 } 9 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 } 10 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 11 sys_write(1, b, k); return 0 12} 13 14func tally(r: *i64, n: i64) -> i64 { 15 var ec: i64 = 0; var i: i64 = 0 16 while i < n { if r[i] != 1 { if ec == 0 { ec = i + 1 } } i = i + 1 } 17 return ec 18} 19 20func main() -> i64 { 21 let fr: *i64 = sys_mmap(8 * 64) as *i64 22 let fl: *i64 = sys_mmap(8 * 64) as *i64 23 let r: *i64 = sys_mmap(8 * 8) as *i64 24 let cnt: *i64 = sys_mmap(8) as *i64 25 let nf: i64 = eng_asm_scan("runtime/_hdl_build/nx_asm_bug_fixture.s" as *u8, fr, fl) 26 cnt[0] = nf 27 r[0] = 0; if nf == 1 { r[0] = 1 } // exactly one bug expected 28 r[1] = 0; if fr[0] == 0 { r[1] = 1 } // and it is %rax (id 0) 29 mt_puts("ENGINEER machine-code scan: flags=" as *u8); mt_num(cnt[0]); mt_puts("\n" as *u8) 30 var i: i64 = 0 31 while i < cnt[0] { 32 mt_puts(" live-across-call: %" as *u8); mt_puts(as_regname(fr[i])) 33 mt_puts(" clobbered by call on line " as *u8); mt_num(fl[i]); mt_puts("\n" as *u8) 34 i = i + 1 35 } 36 let ec: i64 = tally(r, 2) 37 sys_exit(ec) 38 return ec 39}