flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
bitRAKE 30 Mar 2011, 02:24
OS requires alignment and shadow space. If you can guarantee that state prior to API calls then you are in compliance. Leaf node that don't use the API can do whatever.
|
|||
![]() |
|
b1528932 30 Mar 2011, 06:01
Ok, so basically i have to do anything to make rsp aligned to 16 bytes before any api call?
I think its better to do so at the beginning, and then keep track of rsp so its always aligned. |
|||
![]() |
|
bitRAKE 31 Mar 2011, 05:19
API will use the shadow space to store registers, so more that RSP aligned is needed! Look for my examples on this board - I have used some techniques you will like.
http://board.flatassembler.net/topic.php?t=10231 http://board.flatassembler.net/topic.php?p=94910#94910 http://board.flatassembler.net/topic.php?p=109871#109871 Good related discussion: http://board.flatassembler.net/topic.php?t=11133 _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
ProMiNick 09 Nov 2020, 22:54
what do you think
Code: 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 \} } Code: 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 \} } Code: 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 \} } Code: 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 if defined current@frame if current@frame<stackspace current@frame = stackspace end if else if stackspace sub rsp,4*8;stackspace end if end if 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 } four macros instead of big one "macro fastcall proc,[arg]" all rest from proc64.inc untouched. Is this realization has advantages or weaknesses against official realization? I guess in my realization I should remove Code: if defined current@frame if current@frame<stackspace current@frame = stackspace end if else I like pushes - modern CPU are pretty fast to choose coding style based on my own preferences. And in that variant it is close to linuxfastcall but there are 6 regs not 4 like in windows, and that close to linux syscall64 too, there are too 6 regs. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.