flat assembler
Message board for the users of flat assembler.
Index
> Main > invoke and fastcall macro (x64) |
Author |
|
ProMiNick 20 Dec 2021, 20:16
let I explain on another variant
Code: macro invoke proc,[arg] { common fastcall [proc],arg } macro detect@argsize arg { define type@param define definition@param arg match =float value,definition@param \{ define definition@param value define type@param float \} match =addr value,definition@param \{ define definition@param value define type@param addr \} match param,definition@param \{ local opcode,origin size@param = 0 if param eqtype 0 | param eqtype 0f | type@param eq addr size@param = 8 else if param eqtype byte 0 | param eqtype byte 0f match prefix value,definition@param \\{ if prefix eq qword size@param = 8 else if prefix eq dword size@param = 4 else if prefix eq word size@param = 2 else if prefix eq byte size@param = 1 end if \\} else if ~ param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15> virtual origin = $ inc param load opcode byte from origin if opcode = 67h | opcode = 41h load opcode byte from origin+1 end if if opcode and 0F8h = 48h size@param = 8 else if opcode = 66h size@param = 2 else if opcode = 0FFh size@param = 4 else size@param = 1 end if end virtual end if \} } macro __mov reg,src,regd,regw,regb,regxmm { detect@argsize src match param,definition@param \{ if type@param eq float if ~ param eq regxmm if size@param = 4 if param eqtype byte 0 | param eqtype byte 0f mov eax,param movd regxmm,eax else movd regxmm,param end if else if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f mov rax,param movq regxmm,rax else movq regxmm,param end if end if end if if vararg@fastcall & ~ param eq reg movq reg,regxmm end if else if type@param eq addr if ~ param eq reg lea reg,[param] end if else if size@param = 8 if ~ param eq reg mov reg,param end if else if size@param = 4 if ~ param eq regd mov regd,param end if else if size@param = 2 if ~ param eq regw mov regw,param end if else if size@param = 1 if ~ param eq regb mov regb,param end if end if \} } macro __push arg { detect@argsize arg match param,definition@param \{ if type@param eq addr lea rax,[param] push rax else if param eqtype [0] | param eqtype byte [0] if size@param = 8 mov rax,param push rax else if size@param = 4 mov eax,param push rax else if size@param = 2 mov ax,param push rax else mov al,param push rax end if else if size@param = 8 virtual origin = $ mov rax,param load opcode byte from origin+1 end virtual if opcode = 0B8h mov rax,param push rax else push param end if else if param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15> movq rax,param push rax else mov eax,param push rax end if \} } macro fastcall proc,torcx:rcx,tordx:rdx,tor8:r8,tor9:r9,[arg] { common local stackspace,argscount,counter counter = 4 if ~arg eq if argscount and 1 sub esp,8 end if reverse counter = counter + 1 __push arg common end if argscount = counter stackspace = ((argscount and 1) + argscount)*8 if stackspace sub rsp,4*8;stackspace end if __mov r9,tor9,r9d,r9w,r9b,xmm3 __mov r8,tor8,r8d,r8w,r8b,xmm2 __mov rdx,tordx,edx,dx,dl,xmm1 __mov rcx,torcx,ecx,cx,cl,xmm0 call proc if stackspace & ~defined current@frame add rsp,stackspace end if } macro proc [args] { common match name params, args> \{ define@proc name,<params \} } first four params (in linux first six, rsi, rdi added) goes to rcx,rdx,r8,r9, in case of floats via xmm0.xmm1,xmm2,xmm3 respectively. like in x32 first of all in revers order params goes to stack if they are.(rax may be trashed) then they (first ones) goes to registers, (again rax may be trashed) then call happened. In official macro params not separated on that ones that goes to registers & and ones goes to stack, they are counted instead to move first 4 to registers if they are and others to stack. for linux (see libcall same as win fastcall): Code: macro invoke proc,[arg] { common libccall [proc],arg } macro libccall proc,tordi:rdi,torsi:rsi,torcx:rcx,tordx:rdx,tor8:r8,tor9:r9,[arg] { common local stackspace,counter counter = 6*8 if defined current@frame if current@frame<stackspace current@frame = stackspace end if else sub rsp,stackspace end if if ~ arg eq forward counter = counter + 8 common end if stackspace = counter + counter and 8 if ~ arg eq counter = 8 reverse __push arg,stackspace-counter counter = counter + 8 common end if __mov r9,tor9,r9d,r9w,r9b,xmm5 __mov r8,tor8,r8d,r8w,r8b,xmm4 __mov rdx,tordx,edx,dx,dl,xmm3 __mov rcx,torcx,ecx,cx,cl,xmm2 __mov rsi,torsi,esi,si,sil,xmm1 __mov rdi,tordi,edi,di,dil,xmm0 call proc if stackspace & ~defined current@frame add rsp,stackspace end if } macro lcall proc_num,tordi:rdi,torsi:rsi,torcx:rcx,tordx:rdx,tor8:r8,tor9:r9 { __mov r9,tor9,r9d,r9w,r9b,xmm5 __mov r8,tor8,r8d,r8w,r8b,xmm4 __mov rdx,tordx,edx,dx,dl,xmm3 __mov rcx,torcx,ecx,cx,cl,xmm2 __mov rsi,torsi,esi,si,sil,xmm1 __mov rdi,tordi,edi,di,dil,xmm0 mov eax,proc_num syscall } macro proc [args] { common match name params, args> \{ define@proc name,<params \} } and __push for linux slightly differ: Code: macro __push value,offs{ define type@param define definition@param value match =float value,definition@param \{ define definition@param value define type@param float \} match =addr value,definition@param \{ define definition@param value define type@param addr \} detect@argsize size@param,definition@param if type@param eq addr lea rax,[definition@param] mov [rsp+offs],rax else if definition@param eqtype [0] | definition@param eqtype byte [0] if size@param = 8 mov rax,definition@param mov [rsp+offs],rax else if size@param = 4 mov eax,definition@param mov [rsp+offs],eax else if size@param = 2 mov ax,definition@param mov [rsp+offs],ax else mov al,definition@param mov [rsp+offs],al end if else if size@param = 8 virtual origin = $ mov rax,definition@param load opcode byte from origin+1 end virtual if opcode = 0B8h mov rax,definition@param mov [rsp+offs],rax else mov qword [rsp+offs],definition@param end if else if definition@param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15> movq [rsp+offs],definition@param else mov [rsp+offs],definition@param end if } |
|||
20 Dec 2021, 20:16 |
|
Hotwire 23 Dec 2021, 20:52
Many thanks!
|
|||
23 Dec 2021, 20:52 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.