-
Notifications
You must be signed in to change notification settings - Fork 8
/
call_asm_x64_gnu.s
66 lines (53 loc) · 1.48 KB
/
call_asm_x64_gnu.s
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
.globl Call_x64_real
Call_x64_real:
pushq %rbp
movq %rsp,%rbp
subq $32,%rsp # keep space for 4 64bit params
# Store register parameters
movq %rcx,16(%rbp) # ApiFunction
movq %rdx,24(%rbp) # int_registers
movq %r8,32(%rbp) # float_registers
movq %r9,40(%rbp) # stack
# Load up integer registers first...
movq 24(%rbp),%rax # rax = int_registers
movq (%rax),%rcx
movq 8(%rax),%rdx
movq 16(%rax),%r8
movq 24(%rax),%r9
# Now floating-point registers
movq 32(%rbp),%rax # rax = float_registers
movsd (%rax),%xmm0
movsd 8(%rax),%xmm1
movsd 16(%rax),%xmm2
movsd 24(%rax),%xmm3
# Now the stack
movq 40(%rbp),%r11 # r11 = stack
mov 48(%rbp),%eax # eax = nstack
#align stack so *after* the copystack loop it will be 16 bytes
#do 32 bits, GBs of stack params is impossible
mov %eax, %r10d
#if odd set al to 1
and $1,%eax
#boost 1 to 8 if its 1, if its 0 it will remain 0
shl $3,%eax
#rax might be zero or not, all eax ops zero extend upper 32 bits
sub %rax, %rsp
mov %r10d, %eax
# Except not if there isn't any
test %eax,%eax
je docall
copystack:
sub $1,%eax
movq (%r11,%rax,8),%r10
pushq %r10
test %eax,%eax
jne copystack
docall:
# And call
movq 16(%rbp),%r10 # r10 = ApiFunction
subq $32,%rsp # Microsoft x64 calling convention - allocate 32 bytes of "shadow space" on the stack
callq *%r10
#pass through rax and xmm0 to caller
movq %rbp,%rsp
popq %rbp
retq