News:

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

CALL vs INVOKE

Started by Robert Collins, December 31, 2004, 02:29:56 AM

Previous topic - Next topic

Ratch

#15
IDCat,
Quote
I don't really understand macro, making macro, using them is very easy. The macro INVOKIT seems to be very small and with these changes it seems to do the same thing as INVOKE2

     Concise is the word you are looking for.

Quote
     In your solution or in the original INVOKE2 (THAT I DID NOT WRITE) it could be pleasant to add the '@' statement to sepcify an OFFSET but if use it with "@F" or "@B" I am not sure it's OK.

     Defining a single @ with TEXTEQU does not prevent you from using @F, @B, or @@: with INVOKIT or any other MACRO.  You cannot use @F with INVOKE, however.  It is easy to check the previous statements with a simple test program.  That is because INVOKIT is a MACRO, wheareas INVOKE is not.  INVOKE is a built in embedded MASM construct mimicking the MACRO call syntax.

Quote
What I would like is : INVOKXX ANYWHERE,DOMETHING,PARM1,PARM2... and I would use as :

INVOKXX @F,DOSOMETHING,eax,ADDR szString
or
INVOKXX ANYWHERE,DOSOMETHING,eax,ADDR szString

     You can do those things with RPUSHIT and JMP right now.  Why obfuscate your jump destinations by burying them in MACRO parameters?

Quote
I prefer a macro that use the edx register rather than a macro which uses the eax register for creating LEA instructions.

Sometimes the jump macro statement could be calculated, an example :

INVOKXX ANYWHERE,[TabFunc + eax * 4],ebx,ADDR szString

How is it possible to have this.

     Do it by writing a MACRO that outputs a LEA EDX,XXXX.  Writing a MACRO that can evaluate the parameters and generate instructions to compute a value will be complicated and turn it into a "work of art".  It is much better for YOU to write the code to obtain the values before INVOKxx is called.  Simple is best.  Otherwise you try to turn MASM into a "poor man's version of C".  Ratch






Grincheux

<<Concise is the word you are looking for.>>

In French it is easier... Try to say the same thing in French, you will have the same problems as I.

I never use macro in my programs, except INVOKE.

But if it is very hard to call a function I prefer to make myself all the push/jmp statements.
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

Robert Collins

Quote from: IDCat on January 01, 2005, 05:52:50 PM
".......I never use macro in my programs, except INVOKE........"

I understand what you are saying but it might interest you to know that whenever you write any type of Assembly program you are in essense using macros. An instruction is itself a macro. The op-code of any assembly mneumonic is nothing more than an 'index' number into the 'micro-code' routine that processes that instruction.

Grincheux

There are many possibilities for calling a function. Many ways to code. For example the differents versions of INVOKE. These macros would have to be hard-coded into MASM such as the original INVOKE statement.

For me, INVOKE and all its variants are not MACROS. They make part of the language syntax like ".Model", "PROC"...

Perhaps it is why this forum exists...

Thanks :U
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

Robert Collins

Quote from: IDCat on January 01, 2005, 05:52:50 PM

".....I never use macro in my programs, except INVOKE....."



Quote from: IDCat on January 01, 2005, 07:14:55 PM

....For me, INVOKE and all its variants are not MACROS....."


I'm having a hard time understanding this one.

Ratch

     What is and what is not a MACRO?  A MACRO is defined by a MACRO statement followed by a code sequence and ends with a ENDM statement.  INVOKIT, INVOKE2, PUSHIT, RPUSHIT and POPIT to name a very few are MACROS.  INVOKE, PUSH, POP, MOV, etc are not MACROS.  They are built hard coded MASM commands that cannot be changed by the user.  And, of course, if MASM does not support a particular instruction(s), many single and multiple instruction sequences can be defined by the user by using the MACRO capability of MASM. Ratch

Grincheux

When is it better to replace a macro by a function ?

For having smaller code ?
For reducing performance ?
Is there a rule for using macros ?
:bdg
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

Ratch

IDCat,
     A MACRO is great for generating inline code multiple times in either one or several programs.  A PROGRAM FUNCTION is good for executing a subprogram many times in either one or several programs.  A MACRO FUNCTION is used for returning a value during assembly that can be used in other MACRO's.  @ArgRev is an example of a MACRO FUNCTION.  The choice is yours.  Ratch

Robert Collins

Quote from: Ratch on January 01, 2005, 09:27:08 PM
     What is and what is not a MACRO?  A MACRO is defined by a MACRO statement followed by a code sequence and ends with a ENDM statement.  INVOKIT, INVOKE2, PUSHIT, RPUSHIT and POPIT to name a very few are MACROS.  INVOKE, PUSH, POP, MOV, etc are not MACROS.  They are built hard coded MASM commands that cannot be changed by the user.  And, of course, if MASM does not support a particular instruction(s), many single and multiple instruction sequences can be defined by the user by using the MACRO capability of MASM. Ratch

When you say that a macro is defined by a MACRO statement......and ends with a ENDM you are correct but only in the world of MASM. There are other assembly language assemblers that may have a different 'rule' for making a macro. Also, the mneumonics of any assembly language is not the hard coded commands within the MASM or any assembler for that matter but are the hard coded commands of the CPU. MASM only translates them into their binary form. A macro is defined as a composite of other instructions that as a whole make up the operation of the desired results of the macro. There are two types of macros, user-written, which include all the macros you use such as PUSHIT, POPIT etc. User-written macros also include those that are written at the factory but are included in the Assembler package for your convience. The other type of macro is the op-code of the instruction itself. The instructions, for example, PUSH or POP do nothing by themselves. They must have some underlying routine that performs the actual function of the instruction. Below the machine instruction level (we call it assembly code) lies another level of code called the 'micro-code'. Every op-code of every machine instruction is an address of a location within a table that in turn passes control to the micro-code to perform the operation. This is all done at the CPU or chip) level (and it is called the 'instruction fetch'). Since the instructions that you use in your assembly are still not the absolute code they are then refered to as a macro (just not the macro that you are acustomed to using), but they are still macros. The micro-level is the absolute. An instruction at this level is the bottom line and you cannot go any lower than the micro-level (sometimes refered to as 'Firmware').

donkey

I usually define a macro (in assembler) as any instruction that is not part of the x86 instruction set and not a compiler directive (either assembler, resource compiler or linker). So if it generates code that you did not write it is a macro. In my little definition there are intrinsic and user macros, intrinsic macros like INVOKE, .IF, .WHILE etc are built into the assembler, a user macro is one that is written and inserted in the source code. Automated stack frames (PROC in MASM or FRAME in GoAsm) are also macros under my definition.

Of course in Quebecois slang a macro is just a dirty old man :)
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Robert Collins

MACRO was a Roman Praetorian Guard under the reign of Caligula in the movie 'Demetrius and the Glsadiators'

Ratch

#26
Robert Collins,

Quote
There are other assembly language assemblers that may have a different 'rule' for making a macro.

This is the MASMforum.  I am thoroughly MASMatized and have become a MASM fossil.  I was not thinking of or referring to other assemblers.

Quote
Also, the mneumonics of any assembly language is not the hard coded commands within the MASM or any assembler for that matter but are the hard coded commands of the CPU.

    Beg to differ with you on that.  The assembler defines the mnemonics.  The CPU could not care less what you name the instruction. As long as you generate the correct binaries, the instruction will execute.

Quote
A macro is defined as a composite of other instructions that as a whole make up the operation of the desired results of the macro.

Sounds like a definition of a code snippet.  In MASM at least, you don't have a MACRO until it is wrapped in a MACRO-ENDM envelope.

Quote
The other type of macro is the op-code of the instruction itself. The instructions, for example, PUSH or POP do nothing by themselves. They must have some underlying routine that performs the actual function of the instruction.

    The instruction repertory of MASM are not MACROS.  They do have an underlying routine, but it is not the MACRO mechanism available to users.  This is apparent from the quirks that occur when a instruction is duplicated by user written MACROS.  It is fruitless to speculate how MASM does it.  But it is not the MACRO way a user is permitted to do it.

Quote
Every op-code of every machine instruction is an address of a location within a table that in turn passes control to the micro-code to perform the operation. This is all done at the CPU or chip) level (and it is called the 'instruction fetch').

    I would not presume to know whether a Pentium or Athlon decodes its instruction by a table lookup.  They could very well do it that way, but who knows?

Quote
Since the instructions that you use in your assembly are still not the absolute code they are then refered to as a macro (just not the macro that you are acustomed to using), but they are still macros.

    This is getting out of the purview of MASM.  I don't know what INTEL or AMD call the microcode that actually executes their high level instructions.

Quote
An instruction at this level is the bottom line and you cannot go any lower than the micro-level (sometimes refered to as 'Firmware').

    "Firmware" was coined by the hardware engineers to give the illusion that they control software.  It may be low or high level, but it usually is burned onto a memory chip.  Ratch


Robert Collins

OK, you win, Ratch. I made up all that BS anyway.

hutch--

I moved this topic to the Workshop qas it was more discussion than question and answer form.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

gabor

Hi everyone!

At the end this topic about "call vs invoke" turned out to be a topic about macro. However, I would add something to the original topic because I would like to read your opinion!
Say, the calling situation is like this:

   Procedure(param1:DWORD,param2:DWORD,param3:DWORD)

now as I've read I could do this call 2 different ways.

Here's the old one.


...
push DWORD PTR param3
push DWORD PTR param2
push DWORD PTR param1
call Procedure
add esp,12
...
Procedure:
push ebp
mov ebp,esp
push eax
push ebx
push ecx
mov eax,[ebp-8]    ;param1
mov ebx,[ebp-12]  ;param2
mov ecx,[ebp-16]  ;param3
pop ecx
pop ebx
pop eax
pop ebp
ret

In the proc I'm not sure about the ebp indexing, please tell me if I messed up something!

If I used retf 12 I could leave the add esp,12 after the call.

Whith invoke it's easier indeed:

invoke Procedure,param1,param2,param3

Procedure  PROC USES eax ebx ecx,param1:DWORD,param2:DWORD,param3:DWORD
   mov eax,param1
   ...
Procedure  ENDP


Ok, now comes my suggestion.

...
push DWORD PTR param3
push DWORD PTR param2
push DWORD PTR param1
call Procedure
...

Procedure:
xchg ecx,[esp]     ;EIP
xchg eax,[esp-4]   ;param1
xchg ebx,[esp-8]   ;param2
xchg ecx,[esp-16]  ;param3

pop ecx
pop eax
pop eax
ret

The idea is to merge the reading of parameters and pushing the registers. The params in stack are consumed by the proc, so no add esp,12 is needed after the call. Note that the order of popping the regs in the proc is a bit different (the reg containing the last param and xchged with the EIP must be the first)

What do think of it, is it really a more optimal way to handle parameters. Or is it just a slap in sh|t?

I wait your posts!

Greets, Gábor