A question had been posted in ALA about the possibility of using invoke without argument count checking in STDCALL functions. It would be more logic to prefer the C calling convention as it can handle variable number of parameters with the support of the caller balancing the stack. My quick attempt targets academic interest.
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
_invoke MACRO func:REQ,args:VARARG
LOCAL cnt
cnt = 0
FOR item, <args>
cnt = cnt + 1
ENDM ; argument counter from the Masm32 package
invoke @CatStr(<pr>,%cnt) PTR func,args
ENDM
.data
msg db 'Hello!',0
.code
start:
push MB_OK
push OFFSET msg
_invoke MessageBox,0,ADDR msg
invoke ExitProcess,0
END start
This pseudo invoke statement does not check the number of passed parameters in STDCALL functions.
[attachment deleted by admin]
That's a clever way. Good job.
Hi jag,
I am glad that you liked my method.
Here is Iczelion's tutorial #3 rebuilded without parameter number checking. The externals are declared like the following :
EXTERN ExitProcess@4:PROC
ExitProcess EQU <ExitProcess@4>
EXTERN GetCommandLineA@0:PROC
GetCommandLine EQU <GetCommandLineA@0>
[attachment deleted by admin]
Vortex,
This is ground that has been plowed before. Remember this thread from a couple of year ago? Ratch
http://www.masm32.com/board/index.php?topic=99.0
Ratch,
Yes, I remember for that thread. Compared to the previous one, this new algo is more simple, this is why I posted it.
Another version supporting C function calls :
_invoke MACRO funcname:REQ,args:VARARG
LOCAL counter
counter=0
FOR param,<args>
counter=counter+1
ENDM
IF counter EQ 0
call funcname
ELSE
invoke @CatStr(<pr>,%counter) PTR funcname,args
IF ((OPATTR(funcname)) AND 11100000000y) EQ 00100000000y ; Is it a C function?
add esp,4*counter ; Balance the stack
ENDIF
ENDIF
ENDM
[attachment deleted by admin]
From my DOS days:
@pushcall MACRO WhatToCall,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10 ;10 ain't enough for some API calls :)
  IRP rx,<r10,r9,r8,r7,r6,r5,r4,r3,r2,r1>
   IFNB <rx>
      push rx
   ENDIF
  ENDM
  call WhatToCall
ENDM
e.g.
@pushcall LocalAlloc,0,100h,eax
;LocalAlloc consumes two args, leaving eax on the stack
Crude but effective. Some assemblers allow a macro to _shift_ its parameters until the list is empty. Three examples in RosAsm:
[push | push #1 | #+1]
[pop | pop #1 | #+1]
[mov | mov #1 #2 | #+2]
edit:
MASM understands this too:
@pushcall CreateFileA,offset myspec,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0