on application entry: there is a 1MiB - 8KiB area mapped writable and not executable with guard pages on either side, and rsp is set to the top of that. all other registers are set to 0. the ARGC environment variable holds the number of arguments to main. the ARGV0, ARGV1, ARGV2, etc environment variables hold those arguments. for all system calls: rax, rdi, rsi, rdx are in/out paramters. rbx, rbp, rsp, r12-r15 are preserved. rcx, rflags, r8-r11 are clobbered. interrupts (including the timer!) are disabled during system calls. stream result: 0 = success 1 = bad handle 2 = io error 3 = out of bounds 4 = does not exist 5 = not a regular file 6 = not an executable 7 = not writable 8 = not seekable 9 = socket id already used 10 = socket id not in use 11 = socket listener closed 12 = other end closed 13 = already exists 14 = not sized encode color: rax in: 0 edi in: r + g * 256 + b * 65536 eax out: encoded color get framebuffer: rax in: 1 rax out: pointer to framebuffer rdi out: width + height * 2 ** 32 esi out: pitch framebuffer is always 32 bpp. use the encode color syscall to encode colors. pitch is in dwords, not in bytes. open file: rax in: 2 rdi in: pointer to file path rsi in: file path length rdx in: bit 0: allow creation bit 1: only allow creation rax out: stream result rdi out: stream handle (if rax = success) end this thread: rax in: 3 edi in: exit code (signed, only used if this was last thread) get new pages: rax in: 4 rdi in: number of pages to allocate rax out: start of first page the allocated pages are next to each other, writable, and not executable. read key packet: rax in: 5 eax out: key packet create private socket: rax in: 6 rax out: end 1 stream handle rdi out: end 2 stream handle create socket listener: rax in: 7 rdi in: pointer to id string rsi in: id string length rax out: stream result rdi out: listener handle (if rax = 0) stop socket listener: rax in: 8 rdi in: listener handle accept socket connection: rax in: 9 rdi in: listener handle rax out: stream result rdi out: stream handle connect to socket: rax in: 10 rdi in: pointer to id string rsi in: id string length rax out: stream result rdi out: stream handle (if rax = 0) if the listener is closed while this syscall is blocked, rax is set to "socket id not in use" and not "socket listener closed" close stream: rax in: 11 rdi in: stream handle seek stream: returns "not seekable" for sockets rax in: 12 rdi in: stream handle sil in: 0 = relative to beginning 1 = relative to end 2 = relative to current position rdx in: offset (signed) rax out: stream result read from stream: rax in: 13 rdi in: stream handle rsi in: count rdx in: pointer to buffer rax out: stream result write to stream: rax in: 14 rdi in: stream handle rsi in: count rdx in: pointer to buffer rax out: stream result get stream length: returns "not sized" for sockets rax in: 15 rdi in: stream handle rax out: stream result rdi out: stream length (if rax = success) start process: rax in: 16 rdi in: pointer to process start info struct rax out: stream result rdi out: process handle (if rax = success) process start info struct: qword: file path length qword: pointer to file path qword: count of environment variables qword: pointer to array of environment variable structs qword: count of gifted stream ends qword: pointer to array of gifted stream structs environment variable struct: qword: name length qword: pointer to name qword: value length qword: pointer to value gifted stream struct: qword: stream handle here qword: new stream handle in child new handle must be < 65536 end this process: rax in: 17 edi in: exit code (signed) set stream length: returns "not sized" for sockets rax in: 18 rdi in: stream handle rsi in: new length rax out: stream result