The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: James Ladd on May 12, 2005, 09:02:48 AM

Title: stack, words and call ...
Post by: James Ladd on May 12, 2005, 09:02:48 AM
I hope this is a simple question ...

If i push my arguments manually and use call for a routine, do I need to pop the arguments off
the stack after the call if I used the default proc definition ?
eg:
myproc proc arg1:DWORD, arg2:DWORD

Also, how can I push a word and balance the stack ?

rgs, striker
Title: Re: stack, words and call ...
Post by: Petroizki on May 12, 2005, 09:45:04 AM
If you are using stdcall calling convention, you don't need to pop the arguments off the stack, the procedure does this itself. With C -calling convention you can pop the arguments off the stack after the call like this;
push 1
push 2
call myproc
add esp, 8 ; balance stack


You can "push" a word for example like this:
sub esp, 4 ; or push 'someregister', just make sure you make room for the value
mov word ptr [esp], dx ; move WORD to the stack
Title: Re: stack, words and call ...
Post by: James Ladd on May 12, 2005, 10:13:04 AM
 :dazzled:
Title: Re: stack, words and call ...
Post by: Tedd on May 12, 2005, 10:58:31 AM
For most functions in the windows api you don't need to since they do the cleanup themselves.
You just have to watch out for C type functions (such as wsprintf) where you have to do the cleanup - because they can have any number of arguments and the function doesn't know in advance how many that is.
Most functions you'll use will be 'stdcall' - so you don't need to cleanup, but if they're declared as "proto c" then you've got to do it :wink

Usually word arguments are padded with another null word to keep the other arguments aligned, but it depends what the function expects ::)
Title: Re: stack, words and call ...
Post by: hutch-- on May 12, 2005, 11:30:27 AM
James,

Just to make life complicated, here is another way to perform STDCALL.


            .data
              TitleTxt db "MOV stack",0
              MsgTxt db "Hi There",0
            .code

            mov DWORD PTR [esp-16], 0
            mov DWORD PTR [esp-12], OFFSET MsgTxt
            mov DWORD PTR [esp-8], OFFSET TitleTxt
            mov DWORD PTR [esp-4], MB_OK
            sub esp, 16

            call MessageBox
Title: Re: stack, words and call ...
Post by: AeroASM on May 12, 2005, 01:08:09 PM
Quote from: striker on May 12, 2005, 09:02:48 AM
I hope this is a simple question ...

If i push my arguments manually and use call for a routine, do I need to pop the arguments off
the stack after the call if I used the default proc definition ?
eg:
myproc proc arg1:DWORD, arg2:DWORD

Also, how can I push a word and balance the stack ?

rgs, striker

At the top of your source code, you should have the line .model flat,stdcall.
This means that all procs are stdcall by default.
In stdcall the procedure is responsible for stack balancing.

If you push a dword and balance the stack it is like this:

push eax
add esp,4

because a dword is 4 bytes. A word is only two bytes so:

push ax
add esp,2
Title: Re: stack, words and call ...
Post by: doomsday on May 12, 2005, 05:47:48 PM
Quote from: Hutch--Just to make life complicated, here is another way to perform STDCALL.

Hutch,

You're a bad, bad man <g>  While it'd very likely work, it's bad practice to write below (E)SP.

I seem to recall it that writing below the stack pointer caused problems under DOS because TSRs and int. handlers use the same stack as the current program and thus you could end up with stack corruption.  Just as a matter of idle curiosity, does anyone know if writing below the stack pointer does cause any problems under Windows?  I'd guess not, but I'm curious if anyone's tried it.

regards,
-Brent
Title: Re: stack, words and call ...
Post by: Petroizki on May 12, 2005, 06:56:42 PM
Quote from: doomsday on May 12, 2005, 05:47:48 PMJust as a matter of idle curiosity, does anyone know if writing below the stack pointer does cause any problems under Windows?  I'd guess not, but I'm curious if anyone's tried it.
There was some discussion about this in the other forum: http://board.win32asmcommunity.net/index.php?topic=20128.0.

At least some debuggers can mess the data in the negative offsets of the esp.
Title: Re: stack, words and call ...
Post by: MichaelW on May 12, 2005, 08:13:11 PM
Striker,

If your procedure expects a word argument, for a memory operand you could do either of these:

sub   esp,2
push  mem16

push  word ptr 0
push  mem16

And for a register operand, you could just push the dword register.
Title: Re: stack, words and call ...
Post by: hutch-- on May 13, 2005, 12:42:50 AM
 :bg

> You're a bad, bad man

You are probably right but all it does is occupy the same memory as 4 pushes so one of these days I will have a play to see if 4 MOVs are faster than 4 PUSHs.
Title: Re: stack, words and call ...
Post by: raymond on May 13, 2005, 12:56:21 AM
You can certainly achieve the same goal with slight modifications and without taking any potential risk related to writing below the stack pointer.


            sub esp, 16
            mov DWORD PTR [esp], 0
            mov DWORD PTR [esp+4], OFFSET MsgTxt
            mov DWORD PTR [esp+8], OFFSET TitleTxt
            mov DWORD PTR [esp+12], MB_OK
            call MessageBox


Raymond
Title: Re: stack, words and call ...
Post by: James Ladd on May 13, 2005, 03:13:48 AM
OMG - What have I started ?
Title: Re: stack, words and call ...
Post by: hutch-- on May 13, 2005, 03:18:06 AM
 :bg

James,

You are now the victim of a plethora of deviant STDCALL techniques.  :boohoo:
Title: Re: stack, words and call ...
Post by: Petroizki on May 13, 2005, 05:48:21 AM
Quote from: hutch-- on May 13, 2005, 12:42:50 AMYou are probably right but all it does is occupy the same memory as 4 pushes so one of these days I will have a play to see if 4 MOVs are faster than 4 PUSHs.
I hope i'm not going too off-topic, but i just have to say that in my Athlon, three or more mov's are faster than pushes. It also seems that Visual C++/g++ compiler goes heavily on moving the paramaters to the stack, rather than pushing them.
Title: Re: stack, words and call ...
Post by: Vortex on May 13, 2005, 09:53:39 AM
Hi striker,

You can code your own invoke macro, here is 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
Title: Re: stack, words and call ...
Post by: raymond on May 13, 2005, 02:37:02 PM
EGAD. Why reinvent the wheel with such a complex design (probably difficult to understand even by Einstein :P) when the simple invoke instruction is already available in MASM. It may not even be usable with other assemblers.

I guess it's like climbing a mountain. People do it simply because it's there!

Raymond
Title: Re: stack, words and call ...
Post by: Tedd on May 13, 2005, 03:39:09 PM
Quote from: striker on May 13, 2005, 03:13:48 AM
OMG - What have I started ?

For future reference: never ask 'simple' questions on this board :lol
Title: Re: stack, words and call ...
Post by: Vortex on May 14, 2005, 09:16:41 AM
Quote from: raymond on May 13, 2005, 02:37:02 PM
EGAD. Why reinvent the wheel with such a complex design (probably difficult to understand even by Einstein :P) when the simple invoke instruction is already available in MASM. It may not even be usable with other assemblers.

I guess it's like climbing a mountain. People do it simply because it's there!

Raymond


Raymond,

Have a look at here to see why I reinvented the wheel :P

http://www.masmforum.com/simple/index.php?topic=99.0
Title: Re: stack, words and call ...
Post by: hutch-- on May 14, 2005, 09:35:00 AM
 :green

Nah,

We were just trying to lead James astray, walk on the wild side, do it different and still get it to work OK.  :bg
Title: Re: stack, words and call ...
Post by: raymond on May 15, 2005, 02:20:15 AM
QuoteHave a look at here to see why I reinvented the wheel

Thanks for the reminder. I had forgotten that I had already looked at that thread many months ago. Must be age related. :boohoo:

Raymond
Title: Re: stack, words and call ...
Post by: Vortex on May 15, 2005, 05:50:53 PM
No problem Raymond, just as you said the simple invoke macro is enough for general purpose codig. My simple macro example demonstrates the power of Masm macro system.