@@ -3,86 +3,7 @@ ; syscall64 numbers - syscall table must be created first! %include "calls.x86.lin.64.s" -; syscall ops -%define sys.call syscall +; linux uses the common x86-64 ABI +%include "x86.syscall.64.s" -; register order for syscall convention -%define sys.reg.n 7 -%define sys.reg.ret rax -%define sys.reg.0 rax -%define sys.reg.1 rdi -%define sys.reg.2 rsi -%define sys.reg.3 rdx -%define sys.reg.4 r10 -%define sys.reg.5 r8 -%define sys.reg.6 r9 - -; register order for ccall convention -%define ccall.reg.ct 6 -%define ccall.reg.ret rdi -%define ccall.reg.0 rdi -%define ccall.reg.1 rsi -%define ccall.reg.2 rdx -%define ccall.reg.3 rcx -%define ccall.reg.4 r8 -%define ccall.reg.5 r9 - -%macro sys 1-8 -; syscall64 wrapper, ex. `sys sys.write, 1, msg, msg.len` - %assign i 0 - %rep %0 - mov sys.reg. %+ i, %1 ; i'm actually shocked this worked - %rotate 1 - %assign i i+1 - %endrep - syscall -%endmacro - -%macro sys.prep 1-8 - ; for when we need to modify parameters before we - ; make the actual call. - %assign i 0 - %rep %0 - mov sys.reg. %+ i, %1 - %rotate 1 - %assign i i+1 - %endrep -%endmacro - -%macro ccall 1-* - %if %0 > ccall.reg.ct - %assign ct ccall.reg.ct - %else - %assign ct %0-1 - %endif - %assign i 0 - %rotate 1 - %rep ct - ; if the function is well-behaved, all its arguments fit - ; in registers. if not, things get ugly. see below. - mov ccall.reg. %+ i, %1 - %assign i i+1 - %rotate 1 - %endrep - %if %0 > ccall.reg.ct - ; if there are more parameters to a C function than the - ; number of permitted registers, they must be pushed in - ; reverse order to the stack. - ; keep your function signatures under control, people. - %assign ct (%0-ct)-1 - %rotate ct - %rep ct - %rotate -1 - push %1 - %endrep - %rotate ct - push rsp ; it's our responsibility to preserve the stack - %endif - call %1 - %if %0 > ccall.reg.ct - ; the extra arguments are still on the stack; time to - ; dump them back into the Garbage Zone - pop rsp - %endif -%endmacro