nx_nxasm_main.nx source
↩ module page · 61 lines · 1949 B
1// nxasm_main.nx -- CLI driver for nxasm_v2 + elf_writer.
2//
3// Usage: nxasm <input.s> > <output.elf>
4//
5// Reads input.s via sys_read_file, assembles to RV64 machine
6// bytes via nxasm_v2.assemble(), wraps in a static Linux ELF
7// via elf_writer.write_elf(), writes to stdout.
8//
9// Single-step asm+link. For programs whose entire link is a
10// single .s file (the common case for nxc.nx output today),
11// this replaces the entire `gcc-as + ld` chain in verify.sh.
12//
13// Exit codes:
14// 0 success
15// 1 no args
16// 2 read failed
17// 3 assemble failed (negative byte count)
18// 4 write failed
19//
20// Together with nxld_main (which handles multi-object link),
21// these two tools cover every gcc-as + ld invocation we need.
22
23// nx_safety_envelope:
24// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
25// sil_target: SIL1
26// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
27// verdict: NOT_YET_EVALUATED
28
29import "nx_syscalls.nx"
30import "nxasm_v2.nx"
31import "elf_writer.nx"
32
33func main(argc: i64, argv: *i64) -> i64 {
34 if argc < 2 {
35 return __syscall(93, 1, 0, 0, 0, 0, 0)
36 }
37 let path: *u8 = (argv[1]) as *u8
38
39 let len_raw: *u8 = sys_mmap(16)
40 let len_out: *i64 = len_raw as *i64
41 *len_out = 0
42 let src: *u8 = sys_read_file(path, len_out)
43 if src == (0 as *u8) {
44 return __syscall(93, 2, 0, 0, 0, 0, 0)
45 }
46
47 // Assemble. Generous code buffer (4 MB) covers up to ~1 M
48 // instructions; matches nxc.nx's code_buf for compile parity.
49 let code_buf: *u8 = sys_mmap(4194304)
50 let code_len: i64 = assemble(src, *len_out, code_buf, 4194304)
51 if code_len <= 0 {
52 return __syscall(93, 3, 0, 0, 0, 0, 0)
53 }
54
55 // Wrap in ELF + write to stdout.
56 let n: i64 = write_elf(code_buf, code_len, 1)
57 if n < 0 {
58 return __syscall(93, 4, 0, 0, 0, 0, 0)
59 }
60 return __syscall(93, 0, 0, 0, 0, 0, 0)
61}