News:

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

Using function MACRO as proc MACRO

Started by Ficko, June 22, 2010, 01:57:25 PM

Previous topic - Next topic

Ficko

I am trying to trick out MASM to use function MACRO both ways as function or proc.
I may doing it a hard way. :P

My theory is to return <COMMENT *Var*> if proc <%Var> if function.
It is working beautifuly but if I have a "LABEL:" in the same line calling the macro MASM is putting the label somehow after the call. :dazzled:
I don't know why is that and what I can do about it. ::)


.686p
.model flat, stdcall
option casemap :none
includelib kernel32.lib
include kernel32.inc
RtlZeroMemory PROTO :DWORD,:DWORD
Pilot MACRO
invoke RtlZeroMemory,eax,ebx
EXITM <COMMENT *eax*>
ENDM
.code
start: JMP L000
nop
nop
nop
nop
L000: Pilot()
int 3
end start



001A1000   /EB 0B                           JMP SHORT 001A100D  ;Jumping to INT 3 Why????
001A1002   |90                               NOP
001A1003   |90                               NOP
001A1004   |90                               NOP
001A1005   |90                               NOP
001A1006   |53                               PUSH EBX
001A1007   |50                               PUSH EAX
001A1008   |E8 01000000                CALL 001A100E
001A100D   \CC                               INT3

qWord

macro-generated code/data is allways inserted before the line the macro is called from.
EDIT: this only applies to function like macros
FPU in a trice: SmplMath
It's that simple!

Ficko

Quote from: qWord on June 22, 2010, 02:01:16 PM
macro-generated code/data is allways inserted before the line the macro is called from.

Ok.....I can see that.....

And is there a way to call a function macro and ignore the return value? ::)

qWord

FPU in a trice: SmplMath
It's that simple!

Ficko

I did but still dosn't work on "LABEL"  :bg :(


Ficko

Quote from: qWord on June 22, 2010, 02:01:16 PM
macro-generated code/data is allways inserted before the line the macro is called from.

By the way this seem to be just 50% true because if the MACRO is not a function it works fine. :wink

Ficko

Damn!!! :(

This dosn't work either:


option casemap :none
includelib kernel32.lib
include kernel32.inc
RtlZeroMemory PROTO :DWORD,:DWORD
Pilot MACRO
LOCAL A
A = 1
invoke RtlZeroMemory,eax,ebx
IF A
@CatStr(<EXITM !<!>>)
ENDIF
ENDM
.code
start: JMP L000
nop
nop
nop
nop
L000: Pilot()
int 3
end start

qWord

Quote from: Ficko on June 22, 2010, 02:39:49 PMBy the way this seem to be just 50% true because if the MACRO is not a function it works fine. :wink
yep, your right  :U
However, I was takling about function like macros.

why not making two macros(?):
@Pilot() (function) and Pilot (Procedur)
FPU in a trice: SmplMath
It's that simple!

Ficko


why not making two macros(?)


Because I am working on wrappers for my routines in a lib. about 150 procs and I don't want to double the choices have to make. :bg


Ficko

Ok, I may got something could work for me. :wink

It is actually the reverse but may I can achive the same result with it - having a return value or not having one -


.model flat, stdcall
option casemap :none
includelib kernel32.lib
include kernel32.inc
RtlZeroMemory PROTO :DWORD,:DWORD
Pilot MACRO
invoke RtlZeroMemory, eax, ebx
PilotF MACRO
LOCAL A
EXITM <>
ENDM
PilotF()
ENDM
.code
start: JMP L000
nop
nop
nop
nop
L000: Pilot
int 3
end start

jj2007

Here is a Timer() macro that works both ways. The trick is to check the argument for "start"...

Note the .if 1 is not really necessary, but it forces the user to use Timer(start) ... Timer(whatever) together. That trick is to punish users who forget that the first macro puts the GetTickCount result on the stack with a nasty error message :bg

include \masm32\include\masm32rt.inc

Timer MACRO arg
  push ecx ; save some regs
  push edx
  invoke GetTickCount
  ifidni <arg>, <start>
.if 1
pop edx
pop ecx
push eax
EXITM <> ;; return an empty string for Timer(start)
  else
pop edx
pop ecx
pop edx ;; get the value of Timer(start)
sub eax, edx ;; return elapsed milliseconds
.endif
EXITM <eax>
  endif
ENDM

.data?
globdiff dd ?
gtcloops dd ?

.code
start: mov ebx, 20
.Repeat
imul esi, ebx, 10 ; esi=ebx*10
Timer(start)
invoke Sleep, esi
mov edi, Timer(end)
print str$(edi), 9, " expected: "
print str$(esi), ", abs(diff)="
sub edi, esi
.if Sign?
neg edi
.endif
add globdiff, edi
print str$(edi), 13, 10
dec ebx
.Until Zero?
print "Overall difference: "
print str$(globdiff), 13, 10, "wait loops: "
print str$(gtcloops)
getkey
exit
end start

dedndave

did you try putting the label and the macro on seperate lines ?
start:  JMP     L000

        nop
        nop
        nop
        nop

L000:
        Pilot()
        int     3

Ficko

Thanks JJ2007. :wink

But my scenario is a little different.

Here is a mock-up:


DoNeedOffset MACRO Var:REQ
IF ((.TYPE Var) EQ 42)
EXITM @CatStr(<offset >,Var)
ELSE
EXITM <Var>
ENDIF
ENDM
; ------------------------------------------------
IsNested MACRO Param:REQ
LOCAL CParam,Spos
Spos INSTR <Param>,<*>
IF Spos
CParam SUBSTR <Param>,Spos+1
CParam SUBSTR CParam,1,@SizeStr(%CParam)-1
ELSE
CParam TEXTEQU Param
ENDIF
EXITM CParam
ENDM
; ------------------------------------------------
ENDSTRING MACRO Var:=<EAX>
EXITM @CatStr(<COMMENT *>,<Var>,<*>)
ENDM
; ------------- NOT WORKING ON LINES BEGINNING WITH LABEL !! ---------------------
LEN$ MACRO pString
IFNB <pString>
invoke LEN$_,DoNeedOffset(IsNested(pString))
ELSE
call LEN$_
ENDIF
EXITM <COMMENT *EAX*>
ENDM
; ------------- SEEMS TO WORK -------------
LEN$ MACRO _String
LEN$F MACRO pString
IFNB <pString>
invoke LEN$_,DoNeedOffset(IsNested(pString))
ELSE
call LEN$_
ENDIF
EXITM <COMMENT *EAX*>
ENDM
LEN$F(_String)
ENDM
; ------------------------------------------------
FIRSTINDEXOF MACRO pString:REQ,pSearch:REQ,pos:=<1>
LOCAL cSearch
cSearch CATSTR cfm$(pSearch)
invoke FIRSTINDEXOF_,DoNeedOffset(pString),DoNeedOffset(cSearch),IsNested(pos)
EXITM <COMMENT *EAX*>
ENDM


So I can use:

LEN$(AnyString)
FIRSTINDEXOF(Source,Search,eax)

or

FIRSTINDEXOF(Source,Search,LEN$(AnyString))

Ficko

Quote from: dedndave on June 22, 2010, 04:42:43 PM
did you try putting the label and the macro on seperate lines ?

Of course Dave but that would made the system very error prone.

I should have to pay attention anytime writing a label not to write a function after it. :wink

Rockoon

Quote from: Ficko on June 22, 2010, 04:49:57 PM
Quote from: dedndave on June 22, 2010, 04:42:43 PM
did you try putting the label and the macro on seperate lines ?

Of course Dave but that would made the system very error prone.

I should have to pay attention anytime writing a label not to write a function after it. :wink

or, you can simply never write anything else on the same line as a label, like normal people :)
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.