Has anyone a macro to replace the invoke statement?
I need to introduce a special code sequence between the argument push and the call instruction for a new OOP approach.
Posted on 2003-07-24 07:10:44 by Biterider
What's ur calling convention like for your OOP approach?
Posted on 2003-07-24 08:12:41 by roticv
I can use any calling convention, since invoke is flexible. So I'm looking for a macro with the same functionality!
Posted on 2003-07-24 09:20:15 by Biterider
Look in the FASM package: http://www.flatassembler.net
There have one. Maybe you can adapt it for MASM. (Or better pass on to FASM :grin: )
Posted on 2003-07-24 12:09:01 by JohnFound
Here are mine:
pushx MACRO parameters:VARARG

LOCAL param, reversed, c
param TEXTEQU <>
reversed TEXTEQU <>
forc c, <&parameters>
IFIDN <c>, < >
reversed CATSTR param, < >, reversed
param TEXTEQU <>
ELSE
param CATSTR param, <c>
ENDIF
endm
reversed CATSTR param, < >, reversed
param TEXTEQU <>
% forc c, <&reversed>
IFIDN <c>, < >
push param
param TEXTEQU <>
ENDIF
param CATSTR param, <c>
endm
ENDM
popx MACRO parameters:VARARG
LOCAL param, c
param TEXTEQU <>
forc c, <&parameters>
IFIDN <c>, < >
pop param
param TEXTEQU <>
ENDIF
param CATSTR param, <c>
endm
pop param
ENDM
_call MACRO procedure, parameters:VARARG
LOCAL param, reversed
reversed TEXTEQU <>
% for param, <parameters>
reversed CATSTR <param>, <!,>, reversed
endm
% for param, <reversed>
push param
endm
call dword ptr procedure
ENDM


The last one is what you need. The first two others are extended versions of push/pop that accept multiple operands.
Posted on 2003-07-24 20:30:22 by comrade
Here is my macro. Ratch



; ******************************************************************************
RPUSHIT MACRO args:VARARG
%PUSHIT @ArgRev(args)
ENDM
; ******************************************************************************
;-------------------------------------------------------------------------------
INVOKIT MACRO P1:REQ,P2:VARARG
IFNB <P2>
RPUSHIT P2
ENDIF
CALL P1
ENDM
;-------------------------------------------------------------------------------
Posted on 2003-07-24 20:48:01 by Ratch
Does somebody know if there is a way that a macro knows what calling convention is been used?
Posted on 2003-07-25 01:24:23 by Biterider
Set a flag or some... then let the macro check the flag for see what is the callong convention that you are using.. or some like that.. also i have a macro for nasm that let you use locals var with esp and the default ebp without touching your code ;)

Nice day.
Posted on 2003-07-25 17:12:01 by rea
Has anyone a macro to replace the invoke statement?

[size=9]

;:::::::::::::::::::::::::::::::::::::::::

@ArgCount MACRO arglist:VARARG
LOCAL count, arg
count = 0
FOR arg, <arglist>
count = count + 1
ENDM
EXITM %count
ENDM

;:::::::::::::::::::::::::::::::::::::::::

@ArgRev MACRO arglist
LOCAL txt, arg
txt TEXTEQU <>
% FOR arg, <arglist>
txt CATSTR <arg>, <!,>, txt
ENDM
txt SUBSTR txt, 1, @SizeStr(%txt) - 1
txt CATSTR <!<>, txt, <!>>
EXITM txt
ENDM

;:::::::::::::::::::::::::::::::::::::::::

_call MACRO arglist:VARARG

local n, a, sz, q, arg, line, reax
reax = 0

n TEXTEQU @ArgCount( <arglist> )
% FOR arg, @ArgRev( <arglist> )
n TEXTEQU %(n - 1)
IF n EQ 0
IF reax ;; if eax was used report error
IFIDNI <arg>, <eax>
line TEXTEQU %@Line
% ECHO @FileCur(line) : ERROR! Register value overwritten by _call macro.
.ERR
ENDIF
ENDIF
call arg
IF (OPATTR ( arg )) AND 10000000y
;; References an external label
IF ((OPATTR ( arg )) AND 11100000000y) EQ 00100000000y
;; Uses C calling convention (_cdecl)
n TEXTEQU @ArgCount( <arglist> )
add esp, (n - 1) * sizeof DWORD
ENDIF
ENDIF
ELSE
;;IF @InStr(1, <arg>, <addr >) OR @InStr(1, <arg>, <ADDR >)
IF $IsAddr(arg)
a SUBSTR <arg>, 6
IF $IsStack(a) ;; Is relative to SS
lea eax, a
push eax
reax = 1 ;; no more eax
ELSE
push offset a
ENDIF
ELSEIF @InStr(1, @SubStr(<arg>, 1 , 1), <!">)
push $T0(,<arg>,)
;push $TEXT(,<arg>,)
ELSEIF @InStr(1, @SubStr(<arg>, 1 , 1), <&>)
a SUBSTR <arg>, 2
IF $IsStack(a) ;; Is relative to SS
lea eax, a
push eax
reax = 1 ;; no more eax
ELSE
push offset a
ENDIF
ELSE
IF $IsImm(arg)
IF arg EQ 0
IF @SizeStr(%_ZERO_REG_) NE 0
push _ZERO_REG_
ELSE
push 0
ENDIF
ELSE
push arg
ENDIF
ELSE
push arg
ENDIF
ENDIF
ENDIF
ENDM
ENDM

$call MACRO arglist:VARARG
;;EXITM $RMR(_call arglist)
_call arglist
EXITM <eax>
ENDM
[/size]



Does somebody know if there is a way that a macro knows what calling convention is been used?

It's easy with OPATTR operator.
See Chapter 9 "Using Macros" of masm reference. The _call/$call macros recognize _cdecl cc using OPATTR.
Posted on 2003-07-26 10:12:14 by Four-F
Thanks Four-F!
I try to use your _call macro but I miss the following macros and declarations

$IsAddr
$IsImm
$IsStack
$RMR
$T0
$TEXT
_ZERO_REG_

Can you send them to me?
Posted on 2003-07-27 03:07:29 by Biterider
I have a bunch of useful $IsXXX macros:

[size=9]

$IsCodeLabel MACRO Operand:REQ
IF (OPATTR (Operand)) AND 00000001y
;; References a code label
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsMem MACRO Operand:REQ
IF (OPATTR (Operand)) AND 00000010y
;; Is a memory variable or has a relocatable data label
EXITM <-1> ;; True
ELSE
EXITM <0> ;; False
ENDIF
ENDM

$IsImm MACRO Operand:REQ
IF (OPATTR (Operand)) AND 00000100y
;; Is an immediate value
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsDirMemAddr MACRO Operand:REQ
IF (OPATTR (Operand)) AND 00001000y
;; Uses direct memory addressing
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsReg MACRO Operand:REQ
IF (OPATTR (Operand)) AND 00010000y
;; Is a register value
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsNoError MACRO Operand:REQ
IF (OPATTR (Operand)) AND 00100000y
;; References no undefined symbols and is without error
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsStack MACRO Operand:REQ
IF (OPATTR (Operand)) AND 01000000y
;; relative to SS
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsExtLabel MACRO Operand:REQ
IF (OPATTR (Operand)) AND 10000000y
;; References an external label
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsAddr MACRO Operand:REQ
local a
a = 0

IF @SizeStr(<Operand>) GT 5
IFIDNI <addr >, @SubStr(<Operand>, 1 , 5)
a = 1
ENDIF
ENDIF

IF a
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsByte MACRO Operand:REQ
local r, f
f = 0
IF (TYPE Operand) EQ 1
EXITM <-1>
ELSE ; dunno why, but (TYPE al, bl..) doesn't work
FOR r, <al,ah,bl,bh,cl,ch,dl,dh,>
IFIDNI <Operand>, <r>
f = 1
EXITM
ENDIF
ENDM
IF f
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDIF
ENDM

$IsWord MACRO Operand:REQ
IF (TYPE Operand) EQ 2
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM

$IsDword MACRO Operand:REQ
IF (TYPE Operand) EQ 4
EXITM <-1>
ELSE
EXITM <0>
ENDIF
ENDM
[/size]



$RMR and $TEXT are commented out, so forget about it.

$T0 is my old macro to define text. Now there are collection of such macros in Strings.mac (see attach).
At the beginning of Strings.mac there are description and examples how to use it. It also the part of my KmdKit.


ELSEIF @InStr(1, @SubStr(<arg>, 1 , 1), <!">)

push $T0(,<arg>,)


The above lines in _call macro let you define text directly like this:

_call MessageBox, NULL, "Message", "Caption", MB_OK



I wrote _call macro ~1,5 years ago and used it some time, but later i refused to use it.
You can replace push $T0(,<arg>,) with push $CTA0(<arg>), but I can't guarantee it will work properly.

Now i use my text macros (from Strings.mac) like this:
invoke MessageBox, NULL, $CTA0("Message"), $CTA0("Caption"), MB_OK


Or simple $invoke macro:

$invoke MACRO vars:VARARG

invoke vars
EXITM <eax>
ENDM

mov Result, $invoke(MessageBox, NULL, $CTA0("Message"), $CTA0("Caption"), MB_OK)



I played some time with optimization. _ZERO_REG_ is an attempt to optimize code by size.
I used ZREG macro to define zero-register (containing null). And if _call macro meet immediate value 0, it replaces it with zero-register. For ex, push 0 will be push ebx. It's much smaller.

I don't provide you with my zero macros because of they are in inconsistent state. I stop to develop it and I didn't finished them.


I've thrown away not needed lines from _call macro and now it looks like this:

[size=9]

_call MACRO arglist:VARARG

local n, a, sz, q, arg, line, reax
reax = 0

n TEXTEQU @ArgCount( <arglist> )
% FOR arg, @ArgRev( <arglist> )
n TEXTEQU %(n - 1)
IF n EQ 0
IF reax ;; if eax was used report error
IFIDNI <arg>, <eax>
line TEXTEQU %@Line
% ECHO @FileCur(line) : ERROR! Register value overwritten by _call macro.
.ERR
ENDIF
ENDIF
call arg
IF (OPATTR ( arg )) AND 10000000y
;; References an external label
IF ((OPATTR ( arg )) AND 11100000000y) EQ 00100000000y
;; Uses C calling convention (_cdecl)
n TEXTEQU @ArgCount( <arglist> )
add esp, (n - 1) * sizeof DWORD
ENDIF
ENDIF
ELSE
IF $IsAddr(arg)
a SUBSTR <arg>, 6
IF $IsStack(a) ;; Is relative to SS
lea eax, a
push eax
reax = 1 ;; no more eax
ELSE
push offset a
ENDIF
ELSEIF @InStr(1, @SubStr(<arg>, 1 , 1), <!">)
push $T0(,<arg>,)
ELSEIF @InStr(1, @SubStr(<arg>, 1 , 1), <&>)
a SUBSTR <arg>, 2
IF $IsStack(a) ;; Is relative to SS
lea eax, a
push eax
reax = 1 ;; no more eax
ELSE
push offset a
ENDIF
ELSE
push arg
ENDIF
ENDIF
ENDM
ENDM
[/size]
Posted on 2003-07-27 05:59:58 by Four-F
Opss.. Forgot to attach.
Posted on 2003-07-27 06:03:35 by Four-F