News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Need a wee bit of help with a procedure generating Macro!

Started by LimoDriver, April 06, 2007, 03:51:06 PM

Previous topic - Next topic

LimoDriver

Heya All!

This is my version of the IMalloc interface API - I've asked for assistance before, in the Workshop thread 'bug in Alloc' but noone replied regarding the mentioned problem.
The API is working like a charm, but I think I can bake it look better if someone helped me out with a single macro.

I'm talking about the IMallocProc macro which generates all the IMalloc prodedures below - It's only a few lines of code...


    IMallocProc MACRO procName, procOffset, paramCount
    ;{
        if paramCount eq 0
        ;{
            procName PROC public
        ;}
        elseif paramCount eq 1
        ;{
            procName PROC public p1 : DWORD
        ;}
        elseif paramCount eq 2
        ;{
            procName PROC public p1 : DWORD, p2 : DWORD
        ;}
        endif
        ;{
            invoke  IMalloc
           
            .IF eax
            ;{
                if paramCount gt 1
                ;{
                    push    DWORD PTR [ p2 ]
                ;}
                endif

                if paramCount gt 0
                ;{
                    push    DWORD PTR [ p1 ]
                ;}
                endif
           
                push    eax
                mov     eax, [ eax ]
                call    DWORD PTR [ eax + procOffset ]
            ;}
            .ENDIF
       
            ret
        ;}
        procName ENDP
    ;}
    ENDM


First thing, I'd like to make this work for any number of arguments.
I know that there will never be more then 2 parameters passed down to this macro, but I'd really like to know how to do it via a FOR macro loop.


        if paramCount eq 0
        ;{
            procName PROC public
        ;}
        elseif paramCount eq 1
        ;{
            procName PROC public p1 : DWORD
        ;}
        elseif paramCount eq 2
        ;{
            procName PROC public p1 : DWORD, p2 : DWORD
        ;}
        endif


I've tried dozens of combinations, but whatever I do, I get some strage error duing assembly. I can only guess it has to do with spliting the procedure in multiple lines.

For instance, not even the simplest form:


        procName PROC public
       
        if paramCount eq 1
        ;{
            p1 : DWORD
        ;}
        endif
       
        if paramCount eq 2
        ;{
            , p2 : DWORD
        ;}
        endif


... didn't want to compile, and i don't want to BEGIN trying to paste all the diferent versions of FOR I've tried to implement.

Any suggestions are more then welcome. If anyone's interested in usage of this macro, I have attached the full code which evokes the macro - and an example of using the API calls.

Thanx in advance, macro haxorz!

[attachment deleted by admin]

zooba

Use the REPEAT construct and strings:


IMallocProc MACRO procName, procOffset, paramCount
    parameters TEXTEQU <>
    i = 1
    REPEAT paramCount
        parameters CATSTR parameters, <, p>, %i, < : DWORD>
        i = i + 1
    ENDM
   
    procName PROC public @SubStr(%parameters,2)
        ret
    procName ENDP

    %ECHO procName PROC public @SubStr(%parameters,2)
ENDM


The ECHO at the end is to display the generated procedure header.

You should be able to modify this to be able to push the parameters you want, though it is probably easier to take a list of parameters rather than a count. Search for VARARG.

Cheers,

Zooba :U

Jimg

Here's another example-
makeproc macro procName,paramCount
local fmtx,bufx
arg CatStr <procName>, < PROC P1:dword>
fmt textequ <"%li>
num=1
 
repeat paramCount-1
num=num+1
arg catstr arg,<, P>,%num,<:dword>
fmt catstr fmt,< %li>
Endm
fmt catstr fmt,<",0>
.data
fmtx db fmt
.data?
bufx db 100 dup (?)
.code
arg
num=paramCount
repeat paramCount
  arg2 catstr <P>,%num
  push arg2
  num=num-1
endm
push offset fmtx
push offset bufx
call wsprintf
invoke MessageBox,0,addr bufx,0,0
ret
procName endp
endm

makeproc abc,13

makeproc def,5

chkproc proc
invoke abc,1,2,3,4,5,6,7,8,9,10,11,12,13
invoke def,1,2,3,4,5
ret
chkproc EndP


edit: modified to push parameters