// rt/start.s — process entry. Linux sets up the stack so that on // entry [SP] holds argc, [SP+8] starts argv (NULL-terminated array // of *u8), [SP+8+(argc+1)*8] starts envp (also NULL-terminated). // // We pull argc into DI and the argv pointer into SI, then jump to // `main`. ww programs that declare `fn main(argc: i32, argv: **u8) // i32` see them; programs declaring `fn main() i32` simply ignore // the regs. Either way, main's return value is fed to the exit // syscall. // // envp is captured into the rt_envp_slot DATAW cell before CALL main // so lib/os.getenv (via the rt_envp getter below) can walk it. We // compute envp = SP + 16 + argc*8 in AX using three doublings and // adds — w6a's syntax doesn't ship SIB-style indexed addressing // (no `LEAQ 16(SP)(DI*8), AX`), so the explicit shift-by-three is // the portable form. AX/DI/SI are scratch on entry; no callee- // saved discipline applies until we reach main. TEXT _start,$0 MOVQ (SP), DI // argc → DI (1st arg to main) LEAQ 8(SP), SI // &argv[0] → SI (2nd arg to main) MOVQ DI, AX // AX = argc ADDQ AX, AX // AX = argc * 2 ADDQ AX, AX // AX = argc * 4 ADDQ AX, AX // AX = argc * 8 ADDQ SP, AX // AX = SP + argc*8 ADDQ $16, AX // AX = SP + argc*8 + 16 = &argv[argc+1] = envp MOVQ AX, rt_envp_slot(SB) CALL main(SB) MOVQ AX, DI MOVQ $60, AX SYSCALL // rt_envp — getter that returns the envp pointer captured at process // entry. Bound from lib/os via `@symbol("rt_envp") fn rtenvp() **u8;`, // matching the rt_syscall / rt_alloc / rt_abort pattern. Read-only // view of the kernel-supplied table; the bytes live for the process // lifetime. A future setenv that grows the table re-points the slot // (separate task). TEXT rt_envp,$0 MOVQ rt_envp_slot(SB), AX RET // rt_envp_slot — 8-byte writable cell holding the envp pointer. // Initialised to zero in .data; _start overwrites it before // transferring control to main. DATAW gives us the writable .data // slot (w6a has no GLOBL; same shape as lib/log's silent/default/ // global cells in lib/log/log.s). DATAW rt_envp_slot(SB),"\x00\x00\x00\x00\x00\x00\x00\x00"