flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
revolution 04 Aug 2022, 12:53
Each double is 8 bytes.
But i suspect your macro for cinvoke is already doing the stack adjustment for you. You haven't shown your macro implementation for that so we can only guess what it does. Last edited by revolution on 04 Aug 2022, 20:59; edited 1 time in total |
|||
![]() |
|
Roman 04 Aug 2022, 12:55
add esp, 18h show IDA PRO
|
|||
![]() |
|
Roman 04 Aug 2022, 12:59
I using include 'c:\fasmw17316\include\Win32a.inc'
Code: ;from fasmw17316\INCLUDE\MACRO\proc32.inc macro cinvoke proc,[arg] ; indirectly call CDECL procedure { common size@ccall = 0 if ~ arg eq reverse pushd arg size@ccall = size@ccall+4 common end if call [proc] if size@ccall add esp,size@ccall end if } |
|||
![]() |
|
revolution 04 Aug 2022, 13:05
size@ccall should be the size of the pushed arguments, not simply the count * 4.
|
|||
![]() |
|
ProMiNick 04 Aug 2022, 14:17
use
Code: invoke sprintf,ebx,'[%f ,%f ,%f ,%f]',double [resultq],double [resultq2],double [resultq3],double [resultq4] add esp,4*2+8*4;$28 not $18 instead of Code: cinvoke sprintf,ebx,'[%f ,%f ,%f ,%f]',double [resultq],double [resultq2],double [resultq3],double [resultq4] or override pushd in way it properly collect size@ccall for ccalls & not collect it for stdcall(because in stdcall size@ccall is undefined) |
|||
![]() |
|
ProMiNick 04 Aug 2022, 21:53
Roman thou should shame.
That isn`t bug. It is uncorrect using of macros. Every macro have limit of use cases. At some moment adding more use cases bacame too painfull for preprocessor and thou stoped on that macro version that works in all general cases and not become too greedy for preprocessor. thou could add feature in pushd macro that if defined size@ccall size@ccall = size@ccall+4 end if for cases when argument is double. or thou could avoid using cinvoke with double args using "invoke & add esp" pair. or you could fix each time manualy cinvoke sprintf,ebx,'[%f ,%f ,%f ,%f]',double [resultq],double [resultq2],double [resultq3],double [resultq4] store 2*4+4*8 at $-1; imm here is 1 byte size if cinvoke calculate it incorrect - calculate it thourself |
|||
![]() |
|
revolution 04 Aug 2022, 22:10
ProMiNick wrote: Roman thou should shame. It is a bug with the macros in the standard fasm download. The macros should just do the right thing. Don't burden the programmer with small "gotcha" details that can be easily fixed. |
|||
![]() |
|
Roman 04 Aug 2022, 22:49
ProMiNick
I do. Simple write add esp, 16 But problem in macro, how said Revolution. And I found esp spoiling Accidentally. That's reason this topic. |
|||
![]() |
|
Roman 16 Aug 2022, 06:48
What about 64 bits ?
cinvoke sprintf,ebx,'[%f ,%f ,%f ,%f]',double [resultq],double [resultq2],double [resultq3],double [resultq4] First params going in RCX\RDX\R8\R9 Where is going double [resultq3],double [resultq4] ? In [RSP+32] and [RSP+40] ? |
|||
![]() |
|
ProMiNick 14 Sep 2022, 14:11
\INCLUDE\MACRO\ESPTRACE.INC
Code: ; assumption: module is not expected to be used with 64 bit mode macro x86 [symbol] { x86.#symbol equ symbol } ; symlink x86 sub,add,push,pushw,pushd,pushf,pushfw,pushfd,pusha,pushaw,pushad,pop,popw,popd,popf,popfw,popfd,popa,popaw,popad local@trackbase = 0 ; internal stacktrace variable stack@trace equ local@trackbase = local@trackbase + push@ equ sub@ equ pop@ equ (-1)* add@ equ (-1)* x86.f = 1 x86.w = 2 x86.d = 4 x86.a = 8 x86.mode = 32 macro getmode { virtual at 0 push ax x86.mode = $*16 end virtual } ;programmer responsible for correct x86.mode or use only in 32 bit mode by default macro stacktrace pushtype,amount:1,instr& { local .tmp,tmp .tmp: instr load tmp byte from .tmp if tmp = $66 stack@trace pushtype(amount*64/x86.mode) else stack@trace pushtype(amount*x86.mode/8) end if } irp pushpop,push,pop { macro pushpop statement& \{ match first rest,statement: \\{ if eax eqtype first irps sym,statement \\\{ stacktrace pushpop#@,,x86.#pushpop sym \\\} else stacktrace pushpop#@,,x86.#pushpop statement end if \\} \} irp suffix,f,a \{ irp sizemod,w,d \\{ macro pushpop\#suffix\\#sizemod \\\{ x86.#pushpop\#suffix\\#sizemod stack@trace pushpop#@(x86.\#suffix*x86.\\#sizemod) \\\} \\} macro pushpop\#suffix \\{ stacktrace pushpop#@,x86.\#suffix,x86.#pushpop\#suffix \\} \} irp sizemod,w,d \{ macro pushpop\#sizemod value& \\{ x86.#pushpop\#sizemod value stack@trace pushpop#@(x86.\#sizemod) \\} \} } irp subadd,sub,add { macro subadd arg1, arg2 \{ x86.#subadd arg1, arg2 match =esp,arg1 \\{ if (0 eqtype arg2) | ($ eqtype arg2) stack@trace subadd#@(arg2) end if \\} \} } \INCLUDE\MACRO\PUSHD.INC Code: sizeof.byte = 1 sizeof.word = 2 sizeof.dword = 4 sizeof.fword = 6 sizeof.pword = 6 sizeof.qword = 8 sizeof.tword = 12 sizeof.tbyte = 12 sizeof.xword = 16 sizeof.dqword = 16 sizeof.yword = 32 sizeof.qqword = 32 sizeof.zword = 64 sizeof.dqqword = 64 macro pushd value& { match =addr var, value \{ if +var relative to 0 | +var relative to $ pushd var else lea edx, [var] pushd edx end if pushx equ \} match =pushx type [var], pushx value \{ repeat (sizeof.\#type+3) shr 2 pushd [var+4*(((sizeof.\#type+3) shr 2)-%) end repeat pushx equ \} match =pushx [var], pushx value \{ pushd value pushx equ \} match =pushx type num, pushx value \{ if value eqtype byte 0 | value eqtype byte 0:0 | value eqtype byte 0f virtual at 0 if type in <byte,word,dword> dd num else if type in <fword,pword> dp num else if type eq qword dq num else if type in <tbyte,tword> dt num else error value end if dq 0 load ..low dword from 0 load ..mid dword from 4 load ..high dword from 8 end virtual if type in <tbyte,tword> pushd ..high end if if ~type in <byte,word,dword> pushd ..mid end if pushd ..low else pushd value end if pushx equ \} match =pushx , pushx \{ pushd value pushx equ \} restore pushx } \INCLUDE\MACRO\CALL32.INC Code: macro RTLorder [args] { common if ~ arg eq reverse pushd args common end if } macro LTRorder [args] { common if ~ arg eq forward pushd args common end if } CCcleanup equ callee macro cleanup@stack amount { if amount match =callee, CCcleanup \{ virtual \} add esp, amount match =callee, CCcleanup \{ end virtual \} end if } macro stdcall proc,[arg] ; directly call STDCALL procedure { common local tmp tmp = local@trackbase ; required ESPTRACE.INC RTLorder arg call proc cleanup@stack local@trackbase-tmp} macro ccall proc,[arg] ; directly call CDECL procedure { common CCcleanup equ caller stdcall proc,arg restore CCcleanup } macro invoke proc,[arg] { common stdcall [proc],arg } ; indirectly call STDCALL procedure macro cinvoke proc,[arg] { common ccall [proc],arg } ; indirectly call CDECL procedure macro fastcall proc,toECX:ecx,toEDX:edx,[arg] ; directly call FASTCALL procedure { common RTLorder arg if ~edx eq toEDX mov edx,toEDX end if if ~ecx eq toECX mov ecx,toECX end if call proc } macro regcall proc,toEAX:eax,toEDX:edx,toECX:ecx,[arg] ; directly call DELPHI procedure { common LTRorder arg if ~ecx eq toECX mov ecx,toECX end if if ~edx eq toEDX mov edx,toEDX end if if ~eax eq toEAX mov eax,toEAX end if call proc } macro thiscall proc,toECX:ecx,[arg] ; directly call THISCALL procedure { common RTLorder arg if ~ecx eq toECX mov ecx,toECX end if call proc } macro watcomcall proc,toEAX:eax,toEDX:edx,toEBX:ebx,toECX:ecx,[arg] ; directly call WATCOM procedure { common RTLorder arg if ~ecx eq toECX mov ecx,toECX end if if ~ebx eq toEBX mov ebx,toEBX end if if ~edx eq toEDX mov edx,toEDX end if if ~eax eq toEAX mov eax,toEAX end if call proc } win32a.inc Code: ; Win32 programming headers (ASCII) include 'macro/struct.inc' include 'macro/esptrace.inc' ; every stack move affect semiinternal local@trackbase variable include 'macro/pushd.inc' ; overriding pushd for complex vaues include 'macro/proc32.inc' include 'macro/call32.inc' ; override ones defined in proc32.inc, or remove them from proc32.inc include 'macro/com32.inc' include 'macro/import32.inc' include 'macro/export.inc' include 'macro/resource.inc' struc TCHAR [val] { common match any, val \{ . db val \} match , val \{ . db ? \} } sizeof.TCHAR = 1 include 'equates/kernel32.inc' include 'equates/user32.inc' include 'equates/gdi32.inc' include 'equates/comctl32.inc' include 'equates/comdlg32.inc' include 'equates/shell32.inc' include 'equates/wsock32.inc' macro api [name] { if used name label name dword at name#A end if } lastly double equ qword - and that will fix stack for double in ccall, cinvoke for x32 (i canceled from use of word "double", just word "qword" instead) (call32.inc requires esptrace.inc but to way independant from|to pushd.inc which only overrides pushd) |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.