The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Robert Collins on December 31, 2004, 02:29:56 AM

Title: CALL vs INVOKE
Post by: Robert Collins on December 31, 2004, 02:29:56 AM
I see the 'invoke' statement in all assembly source code but very seldom see the 'call' statement. What is the difference? Can I assume that the 'invoke' statement can always be used instead of the 'call' statement?
Title: Re: CALL vs INVOKE
Post by: raymond on December 31, 2004, 02:56:36 AM
Quote from: Robert Collins on December 31, 2004, 02:29:56 AM
Can I assume that the 'invoke' statement can always be used instead of the 'call' statement?

The 'call' statement could ALWAYS be used instead of the 'invoke' statement. The 'invoke' statement could not be used unless:
- the code being called is written as a formal procedure (proc - endp)
- a PROTO is included at the beginning of your source code defining the number and types of parameters required by the procedure.

The main advantage of INVOKE: The assembler uses the PROTO data to check the number and type of parameters used when "invoking" the procedure and issues an error message if they don't match, thus preventing many potential bugs in a program.
A secondary advantage is that it makes the source code easier to read by having the parameters on the same line as the invoked procedure, instead of having to push each parameter individually (and in the proper order).

Raymond
Title: Re: CALL vs INVOKE
Post by: donkey on December 31, 2004, 03:10:11 AM
The PROTO directive is only used in MASM,there are no other assemblers that use it as far as I know, in MASM it is only necessary for forward referenced procedures or external ones. Invoke is a macro that pushes the parameters onto the stack (in STDCALL or reverse order) and executes a call. It is simply a convenient shorthand so instead of doing this...

push Param2
push Param1
call function

You would just use

invoke function, Param1, Param2

Both encode exactly the same, I almost exclusively use invoke, I find the code is clearer and easier to read.
Title: Re: CALL vs INVOKE
Post by: Robert Collins on December 31, 2004, 04:26:37 AM
Quote from: donkey on December 31, 2004, 03:10:11 AM
The PROTO directive is only used in MASM,there are no other assemblers that use it as far as I know, in MASM it is only necessary for forward referenced procedures or external ones. Invoke is a macro that pushes the parameters onto the stack (in STDCALL or reverse order) and executes a call. It is simply a convenient shorthand so instead of doing this...

push Param2
push Param1
call function

You would just use

invoke function, Param1, Param2

Both encode exactly the same, I almost exclusively use invoke, I find the code is clearer and easier to read.

OK, so if I use 'call' then it goes something like this.......


   .
   .
   .
   push   param2
   push   param1
   call   MyProc
   '
   '
   '
MyProc Proc
   pop   param1
   pop   param2
   '
   '
   ret


Now, if I use 'invoke', it goes something like this.....


   .
AnotherProc  PROTO :DWORD,:DWORD
   .
   .
   .
   .
   invoke AnotherProc, Param2, Param1
   '
   '
   '
AnotherProc Proc Param1, Param2
   '
   '
AnotherProc EndP


So, where in the proc that is 'invoked' are the passed parameters? I have not seen any proc that is 'invoked' pop the parameters off the stack. 
     
Title: Re: CALL vs INVOKE
Post by: hutch-- on December 31, 2004, 04:37:15 AM
Robert,

The lowest level you have is mnemonic coding where you use push/call syntax to call other procedures. Thi is fine with simple stuff but it gets progressively more complicate to keep track of as the parameter count gets higher. Where you have high level similations like "invoke" in automates the call interface and has rudimentarytype checking to catch paraeter count and size errors. When you use an API like CreateFont() or CreateWindowEx() which have large parameter counts, you do more work to get them right if you do all of the paraeter pushes manually. "invoke" also uses the "ADDR" operator which handles both .DATA section variables as well as local STACK based variables which are coded differently so as long as you know how they work, you code faster and more reliably using the type checked invoke form.

With MASM the stack corrections are done at the end but are coered by the PROC ENDP format. MASM usually uses RET BYTECOUNT then LEAVE. It is no big deal to manually code a procedure and if you ned the extra register EBP, it allows you to write some very fast code where you need it but you can have the best of both by using the standard options in MASM to turn off stack frames.
Title: Re: CALL vs INVOKE
Post by: donkey on December 31, 2004, 04:38:26 AM
The parametersin a proc are addressed by their relative position to EBP/ESP, there is never a need to POP them. For example

invoke someproc,Param1,Param2

someproc PROC wParam, lParam

mov eax, [wParam]
ret
someproc ENDP

In the case above the 2 parameters are pushed onto the stack by invoke, the stack frame is built with 2 parameters (wParam & lParam),they will resolve to [EBP+8] and [EBP+12]. So the mov encodes as

mov eax, [EBP+8]

[EBP+8] contains the value that was pushed for Param1.

I should note that the stack is perhaps a bit advanced to play with in this way, you are probably better off as a beginner to allow the assembler to handle parameters and such. Above all, since the return address is pushed onto the stack when CALL is executed,do not pop anything off the stack unless you have pushed it from within the procedure. At least not until you gain a greater understanding of the stack and how it works.
Title: Re: CALL vs INVOKE
Post by: Robert Collins on December 31, 2004, 04:59:02 AM
OK, Thanks for the info. I was just curious, I always use invoke anyway.
Title: Re: CALL vs INVOKE
Post by: Vortex on December 31, 2004, 10:45:52 AM
GoAsm appears to be the most flexible to treat invoke, this assembler doesn't require any function prototype to be predefined.
Title: Re: CALL vs INVOKE
Post by: Grincheux on December 31, 2004, 11:24:15 AM
The standard INVOKE statement can be replaced by a new INVOKE2. This one push the parameters in the same maner than INVOKE but does not use the CALL instruction. The CALL is replaced by a PUSH RETADR and is followed by a JMP. The syntax is

INVOKE2  OFFSET REDADDR,DoSomeThingFunc,Param1,Param2

This is very useful is you want to optimize the next instructions :

INVOKE DoSomeThing,Param1,Param2
JMP       AnyWhere

That could be replaced by

INVOKE2  AnyWhere,DoSomeThing,Param1,Param2.

or

INVOKE2 $ + 10,SelectObject,hDC,hBmp

or

INVOKE2 @F,SelectObject,hDC,hBmp
@@ :


A member of this forum wrote the macro for me. Here is the source code

********************* MACRO SOURCE CODE ***************************

@ArgRev macro arglist:REQ
   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

INVOKE2 macro retaddr:REQ, function:REQ, parameters:VARARG
   LOCAL character, edxused, paddr
   
   edxused = 0

   IFNB <parameters>
      %FOR parameter, @ArgRev(<parameters>)
         IF @SizeStr(<parameter>) GT 4
            character SUBSTR <parameter>, 1, 5
               
            IFIDNI character, <ADDR >
               paddr SUBSTR <parameter>, 6, @SizeStr(<parameter>) - 5
               
               IF (OPATTR paddr) AND 00001001b ;; use OFFSET if direct memory address
                  push OFFSET paddr
               ELSE
                  lea edx, paddr
                  push edx
                  edxused = 1
               ENDIF
            ELSE
               push parameter
            ENDIF
         ELSE
            IF edxused NE 0
               .ERRIDNI <parameter>, <edx>, <"edx was used with ADDR, and is now messed up!">
            ENDIF
             
            push parameter
         ENDIF
      ENDM
   ENDIF
   
   IF (OPATTR retaddr) AND 11011011b      ; if is mem address etc..
      push retaddr
   ELSEIF (OPATTR retaddr) AND 00000100b      ; if is constant
      IF retaddr EQ 0
         ; do nothing..
      ELSE
         push retaddr
      ENDIF
   ELSE
      push retaddr
   ENDIF
   
   jmp function
endm
******************* END OF MACRO SOURCE CODE *************************

Title: Re: CALL vs INVOKE
Post by: petezl on December 31, 2004, 12:25:35 PM
Robert,

This thread shows just how flexible the individual code writing styles can be.
It's really worth taking a look at the "Test Department" link for a good insight to using "call", most informative and well commented, even if you decide you don't like the style.
I found that some calls, particularly calling Dll's require a "call" instead of "invoke" which falls into line with Raymonds post.
Other than that, "invoke" makes for fluent code writing (and reading), less mistakes and probably most important in my case is that I can return to it several months later and still understand the program flow.

Peter.
Title: Re: CALL vs INVOKE
Post by: Petroizki on December 31, 2004, 06:24:01 PM
Quote from: IDCat on December 31, 2004, 11:24:15 AMA member of this forum wrote the macro for me. Here is the source code

I believe i made that macro. You should be careful when using the 'ADDR' for effective adresses, there are cases where the macro cannot resolve if the edx is already used and you will end up pushing wrong data to the stack. So you should manually use the 'lea' instruction, this would also usually result in better pairing.

Anyway, i'm making new version of my function macros, and i it will have some changes to these call macros. The real power of using your own invoke macro is to add some nice things; like calling with floating points and strings, like in my fncall.

Vortex,
If GoAsm doesn't need prototypes, then it probably doesn't warn you when calling with wrong amount of parameters? Is there a way to automatically correct the stack when calling with C-calling convention?
Title: Re: CALL vs INVOKE
Post by: donkey on December 31, 2004, 06:45:04 PM
Hi,

No, GoAsm does not do parameter checking, with C calls, like FASM, you must manually correct the stack with ADD ESP, xx. However you could always write a macro to do it using ARGCOUNT, though for myself I am comfortable with correcting the stack myself.
Title: Re: CALL vs INVOKE
Post by: Ratch on January 01, 2005, 03:48:48 AM
Quote@ArgRev macro arglist:REQ
   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

IDCat,
     Look at this link http://www.masmforum.com/simple/index.php?topic=99.0.  Toward the end is my macro for INVOKIT.  Notice the simplified version for @ArgRev.  Notice also the macro for RPUSHIT.  Why can't we do the following?


@        TEXTEQU <OFFSET>
RPUSHIT @ ANYWHERE,PARAM1,PARAM2,PARAM3,.....
JMP DOSOMETHING


     Sure, Invoke2 swallows the JMP, but making the JMP external helps document it.  Ratch
Title: Re: CALL vs INVOKE
Post by: Grincheux on January 01, 2005, 09:46:41 AM
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.

The macro INVOKE2 is very good for me. Now I have too solutions.

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.

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

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.

To the original author of INVOKE2 (it is not the original name) : e-mail me when you have a new version.

Thanks for everyone and happy new year


Title: Re: CALL vs INVOKE
Post by: Vortex on January 01, 2005, 11:08:48 AM
Quote from: donkey on December 31, 2004, 06:45:04 PM
Hi,

No, GoAsm does not do parameter checking, with C calls, like FASM, you must manually correct the stack with ADD ESP, xx. However you could always write a macro to do it using ARGCOUNT, though for myself I am comfortable with correcting the stack myself.

Here is an example of cinvoke macro for GoAsm:

cinvoke(funcname,%1,%2,%3,%4,%5) = \
                               #if ARGCOUNT=1 \
                               invoke funcname  \
                               #elif ARGCOUNT=2   \
                               invoke funcname,%1  \
                               #elif ARGCOUNT=3      \
                               invoke funcname,%1,%2  \
                               #elif ARGCOUNT=4        \
                               invoke funcname,%1,%2,%3 \
                               #elif ARGCOUNT=5          \
                               invoke funcname,%1,%2,%3,%4 \
                               #elif ARGCOUNT=6             \
                               invoke funcname,%1,%2,%3,%4,%5 \
                               #endif                          \
                               #if ARGCOUNT>1                   \
                               ADD ESP,ARGCOUNT-1*4               \
                               #endif
Title: Re: CALL vs INVOKE
Post by: Ratch on January 01, 2005, 05:23:59 PM
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





Title: Re: CALL vs INVOKE
Post by: Grincheux on January 01, 2005, 05:52:50 PM
<<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.
Title: Re: CALL vs INVOKE
Post by: Robert Collins on January 01, 2005, 06:33:46 PM
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.
Title: Re: CALL vs INVOKE
Post by: Grincheux on January 01, 2005, 07:14:55 PM
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
Title: Re: CALL vs INVOKE
Post by: Robert Collins on January 01, 2005, 08:10:52 PM
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.
Title: Re: CALL vs INVOKE
Post by: 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
Title: Re: CALL vs INVOKE
Post by: Grincheux on January 01, 2005, 09:31:00 PM
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
Title: Re: CALL vs INVOKE
Post by: Ratch on January 01, 2005, 09:51:32 PM
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
Title: Re: CALL vs INVOKE
Post by: Robert Collins on January 01, 2005, 10:06:02 PM
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').
Title: Re: CALL vs INVOKE
Post by: donkey on January 01, 2005, 10:23:21 PM
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 :)
Title: Re: CALL vs INVOKE
Post by: Robert Collins on January 01, 2005, 10:43:13 PM
MACRO was a Roman Praetorian Guard under the reign of Caligula in the movie 'Demetrius and the Glsadiators'
Title: Re: CALL vs INVOKE
Post by: Ratch on January 01, 2005, 11:01:16 PM
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

Title: Re: CALL vs INVOKE
Post by: Robert Collins on January 01, 2005, 11:15:07 PM
OK, you win, Ratch. I made up all that BS anyway.
Title: Re: CALL vs INVOKE
Post by: hutch-- on January 02, 2005, 12:36:06 AM
I moved this topic to the Workshop qas it was more discussion than question and answer form.
Title: Re: CALL vs INVOKE
Post by: gabor on March 22, 2005, 01:24:15 PM
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
Title: Re: CALL vs INVOKE
Post by: roticv on March 22, 2005, 04:03:22 PM
It will make your code less verstile as you are forced to do something. Anyway xchg reg, mem is slow if I am not wrong.What is wrong with retn 4*noofparameters?
Title: Re: CALL vs INVOKE
Post by: raymond on March 22, 2005, 04:49:05 PM
Gabor

I strongly believe in the KISS principle. There may be another zillion ways to do the same thing in assembler. However, whenever you complicate things for no obvious reason, you are simply asking for trouble later on.

BTW, you did mess up the EBP indexing. Remember that the stack address is decremented when you push. Therefore, your pushed parameters are at a higher address.

Raymond
Title: Re: CALL vs INVOKE
Post by: Randall Hyde on March 23, 2005, 01:04:50 AM
Quote from: Ratch on January 01, 2005, 11:01:16 PM

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.


Unless, of course, it's buried in a "text equate".
Cheers,
Randy Hyde
Title: Re: CALL vs INVOKE
Post by: Robert Collins on March 23, 2005, 01:38:17 AM
Quote from: Ratch on January 01, 2005, 11:01:16 PM

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.

That is exactly what a macro is. How a macro is defined is language dependant. Did you know that MASM means Macro Assembler and they are not talking about macros that are user defined but rather the assembly language itself. What you and I see as assembly instructions are 'macros' (maybe not as macros in the same sense that we see macros embedded between the MACRO and ENDM statements) to the lower level 'micro-code' that does the instruction fetching which is built into the chip. Actually, assembly op-codes are really more of an 'index' to a lower level subroutine of micro code instructions which carry out the operation of the named instruction.
Title: Re: CALL vs INVOKE
Post by: raymond on March 23, 2005, 02:42:50 AM
QuoteDid you know that MASM means Macro Assembler and they are not talking about macros that are user defined but rather the assembly language itself.

I do agree with you that the first "M" stands for "Macro". However, FYI, prior to "MASM" being issued, MS had issued its ASM assembler which had the same set of instructions and mnemonics as MASM but without the feature for user-defined macros which had not yet been developed.

Raymond
Title: Re: CALL vs INVOKE
Post by: Robert Collins on March 23, 2005, 02:56:37 AM
Quote from: raymond on March 23, 2005, 02:42:50 AM
QuoteDid you know that MASM means Macro Assembler and they are not talking about macros that are user defined but rather the assembly language itself.

I do agree with you that the first "M" stands for "Macro". However, FYI, prior to "MASM" being issued, MS had issued its ASM assembler which had the same set of instructions and mnemonics as MASM but without the feature for user-defined macros which had not yet been developed.

Raymond


Well that definitely makes sense to me so I went back and researched the books I have and I must concede that you are correct about 'M'asm. It does refer to the fact that using MASM you can now assemble user defined macros. My bad.
Title: Re: CALL vs INVOKE
Post by: raymond on March 23, 2005, 03:22:28 AM
QuoteMy bad.

I can't take much credit for my comment because that fact was part of my era. By acknowledging that small inconsequential mistake on your part, you may now heed my signature on more important details in the future. :U :wink

Raymond
Title: Re: CALL vs INVOKE
Post by: Bieb on March 23, 2005, 03:43:57 AM
Ah, now I understand what that means...