libk  Artifact [78d762a0b4]

Artifact 78d762a0b4b2e67c31f5690a0eb362d180882dd637f86c996ef7798c58ab6780:


; vim: ft=nasm
bits 64
%include "syscall.s"
global _start:function
extern _boot
extern entry

_start:
	mov rbp, 0 ; zero the stack base ptr.
	; attempted fix for a difficult-to-
	; reproduce bug

	mov rdi, 0 ; zero rdi - because argc
	; is 32 bits long, we have to store
	; its value in the lower half of rdi.
	; this ensures that the upper half is
	; zeroed as well.

	mov edi, [rsp + 0] ; sizeof arguments
	; first argument to _boot(): argc
	; this is a 32-bit signed(??) integer
	; that is equal to the number of
	; elements in argv (see below). it is
	; not strictly necessary, because argv
	; is per spec always null-terminated,
	; but we pass it just in case. it is
	; also used for finding the environment
	; below.

	lea rsi, [rsp + 8] ; &arguments
	; 2nd argument to _boot(): ptr to argv
	; this points to an array of strings
	; containing the program's command line
	; arguments. _boot() does not need to 
	; parse this, but it does need to store
	; it in the structure passed to main()
	; this exists on the stack, right above
	; argc

	lea rdx, [rsp + rdi * 8 + 16] ; &environment
	; third argument to _boot(): ptr to envp
	; this points to the list of environment
	; variables for the running program. it
	; is the responsibility of _boot to parse
	; this list and arrange it into a set of
	; legible and useful C arrays. it exists
	; above the argument list, the math is
	; stack pointer + argc*pointers(8 bytes)
	; + 16 bytes (argc itself and the
	; terminating null from argv)

	mov rax, 0 ; zero out %rax
	; this is required by the C ABI, and is
	; reputedly necessary for compatibility
	; with icc, intel's own proprietary C
	; compiler.

	call _boot ; invoke the start function
	; that will set up the runtime and
	; construct the necessary structures
	; that will be bassed to libc.

	; boot has returned and left its
	; return value in the register %rax.
	; regardless of the size of the
	; return value of main(), _boot always
	; returns the system word length.

	mov sys.reg.1, sys.reg.ret ; fill in
	; the return value as exit's argument

	mov sys.reg.0, 60 ; set %rax to
	; the syscall number of exit

	sys.call ; invoke the kernel