Hello,
I search a simple sample of a masm proc using VARARG (proc C) and showing how to retrieve the number of arguments?
Hello ToutEnMasm,
A proxy invoke macro can do the job to count the number of parameters :
_invoke MACRO func:REQ,args:VARARG
invkcounter=0
FOR param,<args>
invkcounter=invkcounter+1
ENDM
pcount TEXTEQU %(invkcounter)
IF invkcounter EQ 0
call func
ELSE
invoke func,args
ENDIF
ENDM
include \masm32\include\masm32rt.inc
include invoke.inc
.data
format db 'This %s %s %s.',13,10,0
arg1 db 'is',0
arg2 db 'test',0
arg3 db '1',0
.data?
buffer db 256 dup(?)
.code
start:
_invoke wsprintf,ADDR buffer,ADDR format,\
ADDR arg1,ADDR arg2,ADDR arg3
% echo Number of parameters = pcount
_invoke StdOut,ADDR buffer
% echo Number of parameters = pcount
invoke ExitProcess,0
END start
A proxy invoke macro is a soluce to consider.
I have study a way to solve the probem with the dump of the call.
Quote
;------------------------- C call --------------------------------------------------------
000000CB: 6A 03 push 3
000000CD: 6A 02 push 2
000000CF: 6A 01 push 1
000000D1: E8 2A FF FF FF call _variable
000000D6: 83 C4 0C add esp,0Ch ;<<<< search byte OCh
;----------------------- end of call --------------------------------------------------------
My idea was to get the 0Ch value who is the size of data pushed on stack.
This seems to work.
variable PROC C fgh:DWORD,XXX:VARARG
local ARG@:DWORD,NBarg:DWORD
Local arg1:DWORD,arg2,arg3
mov eax,ebp ;ebp = esp apres sauvegarde de ebp
add eax,4 ;passe ancienne valeur ebp,push ebp
mov edx,[eax] ;adresse de retour dans edx
add eax,4 ;adresse first arg
mov ARG@,eax
xor ecx,ecx
mov byte ptr cl,[edx+2] ;contenu de l'adresse de retour 83 c4 0c o ,on prend 0c
shr ecx,2 ;divise 4
mov NBarg,ecx ;Nb argument dword
;-------------------------- All done ------------------------------------------
mov edx,[eax]
mov arg1,edx
mov edx,[eax+4]
mov arg2,edx
mov edx,[eax+8]
mov arg3,edx
.data
Tampon db MAX_PATH dup (0)
.code
invoke sprintf,addr Tampon,TXT("Number of arg : %u ,Arg1 :%u ,Arg2:%u,Arg3 : %u "),NBarg,arg1,arg2,arg3
invoke MessageBox,NULL,addr Tampon,TXT("c variable resultat"),MB_OK
ret
variable ENDP
Need just now a little improvement