.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 movq 48(%rbp),%rax # rax = nstack # Except not if there isn't any testq %rax,%rax je docall copystack: subq $1,%rax movq (%r11,%rax,8),%r10 pushq %r10 testq %rax,%rax 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 addq $32,%rsp # restore stack # Store return value movq 56(%rbp),%r10 # r10 = iret movq %rax,(%r10) movq 64(%rbp),%r10 # r10 = dret movsd %xmm0,(%r10) movq %rbp,%rsp popq %rbp retq