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}