1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm
; syscall64 numbers - syscall table must be created first!
%include "calls.x86.lin.64.s"
; syscall ops
%define sys.call syscall
; 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
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm
; syscall64 numbers - syscall table must be created first!
%include "calls.x86.lin.64.s"
; linux uses the common x86-64 ABI
%include "x86.syscall.64.s"
|