flat assembler
Message board for the users of flat assembler.

Index > Windows > restore stack after cdecl

Author
Thread Post new topic Reply to topic
wisepenguin



Joined: 30 Mar 2005
Posts: 129
wisepenguin
Code:
; stack.asm
; to get used to the stack, gets command line and prints it in messagebox

format PE GUI 4.0
include "win32axp.inc"

.data
_message db "Command line=%s", 0
_ok db "Did it work ok ?", 0

.code
start:
        push ebp        ; save ebp
        mov ebp, esp
        sub esp, 256    ; 256 chars
        mov esi, esp    ; save the address for later use

        call [GetCommandLine]
        ;invoke GetCommandLine

        push eax
        push _message
        push esi
        call [wsprintf]
; if i comment the next three "pops" it still works
        pop ebx
        pop ebx
        pop ebx
        ;cinvoke wsprintf, esi, _message, eax

        push MB_OK
        push NULL
        push esi
        push HWND_DESKTOP
        call [MessageBox]
        ;invoke MessageBox, HWND_DESKTOP, esi, NULL, MB_OK

        mov esp, ebp    ; restore stack pointer
        pop ebp

        invoke MessageBox, HWND_DESKTOP, _ok, NULL, MB_OK

        invoke ExitProcess, 0
.end start
        ; END
    


wsprintf is a cdecl function so its my responsibility to restore the stack, and thats the three "pop"s. but it still works if i take them out and i do not understand why.
i read up about the cdecl and stdcall and all the examples show "pops" after a cdecl.

this is from the microsoft documentation, printf is a cdecl function

Code:
mov  eax, offset world
      push eax
      mov  eax, offset hello
      push eax
      mov  eax, offset format
      push eax
      call printf
      //clean up the stack so that main can exit cleanly
      //use the unused register ebx to do the cleanup
      pop  ebx
      pop  ebx
      pop  ebx
    
[/code]
Post 03 Aug 2005, 17:27
View user's profile Send private message Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 977
Location: Czechoslovakia
MazeGen
That's because the code, following the wsprintf call, doesn't depend on previous stack state. Even POP EBP is unnecessary - your program doesn't depend on its value.

I mean, if you comment that three pops, POP EBP will not match PUSH EBP, but PUSH ESI. Your program will still work, because you never use EBP after POP EBP.

Try to put some important value to EBP (e.g. offset of _ok) just before PUSH EBP and your program will not work correctly, when you comment that three pops:

Code:
.code
start:
        mov ebp,_ok
        push ebp        ; save ebp
        mov ebp, esp 

        ...

        mov esp, ebp    ; restore stack pointer
        pop ebp

        invoke MessageBox, HWND_DESKTOP, ebp, NULL, MB_OK

        ...
    
Post 03 Aug 2005, 18:03
View user's profile Send private message Visit poster's website Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Btw, don't use pop to clean the stack - use "add esp, <whatever>".
Post 03 Aug 2005, 18:44
View user's profile Send private message Visit poster's website Reply with quote
wisepenguin



Joined: 30 Mar 2005
Posts: 129
wisepenguin
f0dder: ok will do, i will remember that. is the microsoft code wrong then using pops ?
Post 03 Aug 2005, 21:55
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Doing pops (probably) isn't wrong, but it's less efficient (you can adjust by some amounts with less opcode bytes with pop, but the code is slower). Has MS coded like this? Eek!
Post 04 Aug 2005, 00:58
View user's profile Send private message Visit poster's website Reply with quote
DC740



Joined: 01 Oct 2004
Posts: 74
Location: Argentina
DC740
"Btw, don't use pop to clean the stack - use "add esp, <whatever>"."

i'm a newbie and i would like to know more about this topic, any suggestion? maybe some texts about this...(anyway i'm searching in google right now)

thanx
Post 04 Aug 2005, 01:09
View user's profile Send private message Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
If you use add esp, X then it takes always one instruction, no matter how many parameters the function call took. However, using pop requires a pop for each parameter of the function call.

So if you have a function that takes ten parameters, you can either do a single add esp, 40 or you can do ten pop's. Clearly it is faster and smaller to do a single add esp, x.
Post 04 Aug 2005, 03:52
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Not to mention that "add esp, X" only modifies the register, while pop has to read memory, trashes a register, and has multiple modifications of ESP.

You might want to look at fasm's proc macros to automate the stack cleanup...
Post 04 Aug 2005, 11:21
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.