Code:
;http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspxformat ms coff


include 'u:\fasm\INCLUDE\win32wx.inc'
public _syscall64
section '.text' code readable executable


; Converts the arguments and then executes SYSCALL
; 1. Param: Count of args to pass to syscall
; 2. Param: Syscall id
; 3. - X. Param: Params for syscall
_syscall64:
	; Those registers are pushed here so that the LEAVE instr cleans up the converted params without me needing to
	; calc how much space those needed. Seriously what's 4*3 again?
	push edi
	push ebx
	push edx ; used by the x64 code
	
	push ebp
	mov ebp, esp
	
	; Alloc space for params
	mov ecx, [ebp + 4*3 + 0x08] ; cnt
	cmp ecx, 4 ; Reserve shadow space
	jge @f
	mov ecx, 4
@@:
	shl ecx, 3
	sub esp, ecx
	
	and esp, 0xFFFFFFF0 ; Align stack
	
	; Convert params to x64
	mov edi, esp ; Destination
	mov ecx, [ebp + 4*3 + 0x08] ; Count
	lea ebx, [ebp + 4*3 + 0x10] ; Source for params
CONVERT_PARAMS_LOOP:	
	test ecx, ecx
	je @f
	
	mov eax, [ebx]
	stosd ; mov dword[edi], dword[eax] edi += 4
	mov eax, 0
	stosd ; [edi] = 0 edi += 4
	add ebx, 4 ; srcPtr++
	dec ecx    ; cnt--
	jmp CONVERT_PARAMS_LOOP
	
@@:	
	;mov eax, [ebp + 4*3 + 0x0C] ; Get syscall id
	call 0x33:X64_START
X86_RETURN_FROM_X64:	
	leave
	pop edx
	pop ebx
	pop edi
	ret
			
;align 16	
X64_START:
use64
	mov eax, dword [ebp + 0x18] ; Get syscall id (4*3 = saved registers, )
	; Get args from shadow space
	mov rcx, [rsp + 8]
	mov rdx , [rsp + 0x10]
	mov r8, [rsp + 0x18]
	mov r9, [rsp + 0x20]
	
	mov     r10,rcx
	syscall
use32 
	retf