Author Topic: Proc masm using VARARG  (Read 276 times)

TouEnMasm

  • Member
  • *****
  • Posts: 1805
    • EditMasm
Proc masm using VARARG
« on: August 05, 2021, 03:01:35 AM »
Hello,
I search a simple sample of a masm proc using VARARG (proc C) and showing how to retrieve the number of arguments?
Fa is a musical note to play with CL

Vortex

  • Member
  • *****
  • Posts: 2593
Re: Proc masm using VARARG
« Reply #1 on: August 05, 2021, 04:46:01 AM »
Hello ToutEnMasm,

A proxy invoke macro can do the job to count the number of parameters :

Code: [Select]
_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

Code: [Select]
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

TouEnMasm

  • Member
  • *****
  • Posts: 1805
    • EditMasm
Re: Proc masm using VARARG
« Reply #2 on: August 05, 2021, 06:43:38 AM »
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.
Code: [Select]
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




Fa is a musical note to play with CL