News:

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

Macro simulating invoke

Started by Vortex, December 21, 2004, 07:18:21 PM

Previous topic - Next topic

Vortex

Hi friends,

Here is a macro example simulating invoke, the attachment contains an example.
_invoke MACRO funcname:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20
local pos,counter
counter=0

    FOR arg,<p20,p19,p18,p17,p16,p15,p14,p13,p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>

        IFNB <arg>
             
             counter=counter+1
             pos=@InStr(1,arg,<ADDR>) OR @InStr(1,arg,<addr>) OR @InStr(1,arg,<Addr>)

             IF pos

                IF (OPATTR(@SubStr(arg,%pos+5))) EQ 98
                        lea eax,@SubStr(<arg>,%pos+5)
                        push eax
                ELSE
                        push OFFSET @SubStr(<arg>,%pos+5)
                ENDIF

             ELSE
                        push arg
             ENDIF
        ENDIF
    ENDM
call funcname
ENDM

The variable counter holds the number of passed parameters.

[attachment deleted by admin]

Tedd

Very nice.

Just to be annoying - how about a warning if eax gets over-written upon the lea? :bdg
No snowflake in an avalanche feels responsible.

Vortex

Quote from: Tedd on December 22, 2004, 04:37:30 PM
Very nice.

Just to be annoying - how about a warning if eax gets over-written upon the lea? :bdg


Yes, you can insert the directive echo to output warnings.

raymond

Just curious. What would be the advantage of using such a macro instead of the invoke statement?

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Mark_Larson

Quote from: raymond on December 23, 2004, 01:32:52 AM
Just curious. What would be the advantage of using such a macro instead of the invoke statement?

Raymond


  The current invoke macro does not support calling a pointer to an address.  If you have your own macro, you can modify it to support that.

BIOS programmers do it fastest, hehe.  ;)

My Optimization webpage
htttp://www.website.masmforum.com/mark/index.htm

raymond

When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

rea

If you overwrite completely, even you can automatically do the way how goasm (as I know) pass the addresses of locals :).

Ratch

Here is my version of a INVOKE macro.  Ratch



;*******************************************************************************
; @ArgRev :  MACRO FUNCTION                                                    *
;                                                                              *
; Called by: @ArgRev(P1,P2:VARARG)                                             *
;                                                                              *
; Returns :  VARARG list in reverse order                                      *
;-------------------------------------------------------------------------------
@ArgRev MACRO P1,P2:VARARG
LOCAL TXT
TXT TEXTEQU <P1>

FOR ARG,<P2>
 TXT CATSTR <ARG>,<!,>,TXT
ENDM

EXITM <TXT>
ENDM
;*******************************************************************************
PUSHIT MACRO P1:VARARG
FOR arg,<P1>
 PUSH arg
ENDM
ENDM
;*******************************************************************************
RPUSHIT MACRO P1:VARARG
%PUSHIT @ArgRev(P1)
ENDM
;-------------------------------------------------------------------------------
INVOKIT MACRO P1:REQ,P2:VARARG
IFNB <P2>
 RPUSHIT P2
ENDIF
CALL P1
ENDM
;-

Robert Collins

Quote from: Ratch on December 23, 2004, 04:44:51 AM
Here is my version of a INVOKE macro.  Ratch



;*******************************************************************************
; @ArgRev :  MACRO FUNCTION                                                    *
;                                                                              *
; Called by: @ArgRev(P1,P2:VARARG)                                             *
;                                                                              *
; Returns :  VARARG list in reverse order                                      *
;-------------------------------------------------------------------------------
@ArgRev MACRO P1,P2:VARARG
LOCAL TXT
TXT TEXTEQU <P1>

FOR ARG,<P2>
 TXT CATSTR <ARG>,<!,>,TXT
ENDM

EXITM <TXT>
ENDM
;*******************************************************************************
PUSHIT MACRO P1:VARARG
FOR arg,<P1>
 PUSH arg
ENDM
ENDM
;*******************************************************************************
RPUSHIT MACRO P1:VARARG
%PUSHIT @ArgRev(P1)
ENDM
;-------------------------------------------------------------------------------
INVOKIT MACRO P1:REQ,P2:VARARG
IFNB <P2>
 RPUSHIT P2
ENDIF
CALL P1
ENDM
;-


I'm not trying to be sarcastic but I don't like the macro name PUSHIT because it looks like.........well you can see what I mean.

Ratch

To Robert Collins,
     The MACRO's name is easily changed if it offends you.  The complement to PUSHIT is POPIT.  What do you think about the conciseness of the INVOKIT MACRO?  Ratch

Robert Collins

Quote from: Ratch on December 23, 2004, 06:09:47 AM
To Robert Collins,
     The MACRO's name is easily changed if it offends you.  The complement to PUSHIT is POPIT.  What do you think about the conciseness of the INVOKIT MACRO?  Ratch

The name is OK. I was just kidding about saying I dont like it. Its just that when I looked at it the last four letters stood out more profoundly. I have seen many names used in programming that just happen to fall into this category. I only said that because I know how some of the programmers where I work would use that name in their normal daily activities. Anyway, it's perfectly fine with me.

Vortex

Hi Raymond,

With a macro simulating invoke, you don't need define function prototypes. A simple extrern directive is enough to declare an external function.

hutch--



Quote
The current invoke macro does not support calling a pointer to an address.  If you have your own macro, you can modify it to support that

This is not exactly the case, it all in the prototype. Quoting directly from the "macros.asm" file in MASM32,

comment * -----------------------------------------------------------------

   NOTES on DDPROTO macro

   This macro is for producing prototypes for functions where the start
   address is known and the parameter count is known. It requires a named
   DWORD sized entry in the .DATA or .DATA? section which has the start
   address written to it before the function is called.

        EXAMPLE:
        .data?
          user32_msgbox dd ?            ; << The named variable

        msgbox DDPROTO(user32_msgbox,4) ; create prototype

        This is expanded to the following. The TYPEDEF refers to
        the macro "pr4" in the WINDOWS.INC file.

        pt4 TYPEDEF PTR pr4
        msgbox equ <(TYPE pt4) PTR user32_msgbox>

        The address must be written to the DWORD variable before it can
        be called. This can be LoadLibrary/GetProcAddress or it can be
        an address recovered from a virtual table in a DLL or any other
        viable means of obtaining the start address of a function to call.

        invoke msgbox,hWnd,ADDR message_text, ADDR title_text,MB_OK

        ----------------------------------------------------------------- *

If you have the start address you want to use and know the number of parameters, you create a prototype for it using this or a similar macro then use INVOKE like normal.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Vortex

Here is a situation where an alternate invoke macro can be used

Tricks to use Masm with import libraries created directly from DLLs. These are:
i) Creating import libraries containing function names with no decoration
ii) Using the syscall convention
iii) Using an alternate invoke macro to call API functions

.386
.model flat, syscall ; SYSCALL convention
option casemap:none
include \masm32\include\windows.inc
include invoke.inc

extern ExitProcess:proc
extern MessageBoxA:proc
MessageBox equ <MessageBoxA>

includelib kernel32.lib
includelib user32.lib

.data
MsgCaption      db "Iczelion's tutorial no.2",0
MsgBoxText      db "Win32 Assembly is Great!",0

.code
_start:
_invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
_invoke ExitProcess,NULL

END _start

[attachment deleted by admin]