Hi Klod,
Jeez, that's a tricky one!!! At first, I didn't see how this was going to work at all. "ADDR foo" is *one* parameter, we're going to have to "parse" it, right? Wrong! My tired old eyes were missing the comma in the %define. We're making *two* parameters out of it!
So what Pedro's doing is to rotate an extra time, check the "previous" (or "next") parameter for "ADDR_". If so, rotate to the "real" parameter, lea and push it, and "rotate back" to skip the "ADDR_" (fake) parameter. If it *isn't* ADDR_, undo the "extra" rotate and proceed...
Pedro introduces an "assemble-time variable", "i", which mirrors the parameter count, "%0", initially. This gets decremented an "extra" time if ADDR_, and causes an "early exit" from the %rep loop. There may be a way to get around this, but it may be necessary - my best attempt so far does the lea/push correctly(?), but since we've handled two parameters per loop (if ADDR), this pushes one too many (push Hexprint, e.g.) before "call Hexprint". Re-introducing that (I called it "repcount") seems to fix it
One thing I noticed that's going to cause you trouble is the brackets "[]". You've got "[%1]" in the macro, and call it as "ADDR_ [@string]". This results in "lea [[@string]]" - "expression syntax error"! Programmer's choice which place you do it, but not both.
I think your "%elifnum" will work if you make it "$elifnum %1". Arguably, Nasm ought to complain about just "%elifnum" without a parameter... but it doesn't.
This is what I've got... so far...
%define ADDR "ADDR_",
%macro scall 1-*.nolist ;Windows StdCall: push last value first, no cleanup
%ifndef %1_defined ;define external functions
extern %1
%endif
%define _proc %1
%assign repcount %0
%rep %0 - 1
%rotate -1
%rotate -1 ; "extra" rotate
%ifidni %1,"ADDR_"
%error "ADDR is used"
%rotate 1
lea eax, [%1]
push eax
%rotate -1
%assign repcount repcount - 1
%else
%rotate 1 ; undo the "extra"
%endif
%ifstr %1
;;;;;%ifstr %-1
%error "We have a string argument"
mac_pushstring %1
%elifid %1
push dword %1
%error "We have a label"
%elifnum %1
push dword %1
%error "We have a number"
%else
;%error "unspecified Argument"
push dword %1
%endif
%assign repcount repcount - 1
%if repcount >= 1
%exitrep
%endif
%endrep
call _proc
%endmacro
This "seems to work" - not well-tested, 'cause I had to comment out a lot of stuff, lacking the full macro-set (and Windows), to get it to assemble at all. See if it helps... I think you're closing in on it!
Best,
Frank