The MASM Forum

General => The Campus => Topic started by: Niu on January 02, 2014, 09:49:39 PM

Title: program crash wsprintf
Post by: Niu on January 02, 2014, 09:49:39 PM
Hello everyone,
I've started to (try) program asm and I have a problem which I do not quite understand.
i hope someone can help me here to understand the problem.
I have following code:

.Const

.Data?

.Data
hInst HINSTANCE NULL

message2 DB "Hello World!", 0
buffer DB 512 Dup (?)
format DB "HH %s", 0

.Code

start:
Invoke GetModuleHandle, NULL
Mov hInst, Eax
Call Main
Invoke ExitProcess, 0

Main Proc Private

Call Mwsprintf
inkey


Ret
Main EndP


Mwsprintf Proc Near

;funktioniert
;Invoke wsprintf, Addr buffer, Addr format, Addr message2   
;Invoke StdOut, Addr buffer

;funktioniert nicht
Push Offset message2
Push Offset format
Push Offset buffer
Call wsprintf
Invoke StdOut, Addr buffer

Ret
Mwsprintf EndP
End start


and it works fine if i use


Invoke wsprintf, Addr buffer, Addr format, Addr message2   
Invoke StdOut, Addr buffer


As I have read the following notation should do the same, am I right?


Push Offset message2
Push Offset format
Push Offset buffer
Call wsprintf
Invoke StdOut, Addr buffer


but as soon as I use the second notation the programm crashes.
Can someone tell me what I'm doing wrong?

Thanks,
and a happy new year  :biggrin:

Title: Re: program crash wsprintf
Post by: dedndave on January 02, 2014, 10:07:16 PM
if you look inside the \masm32\include\user32.inc file, you will find the function is prototyped as follows:
wsprintfA PROTO C :VARARG

the method you are attempting will work for StdCall functions
however, for the "C" calling convention, the parameters are left on the stack
by using the masm internal INVOKE macro, the stack is adjusted after the call
when you use CALL, the stack is not balanced
so, the return address for the Mwsprintf is not properly found - and the crash occurs
(actually, the Mwsprintf RET instruction gets "Offset buffer" from the stack and tries to execute it)

if you do this, it will work
Push Offset message2
Push Offset format
Push Offset buffer
Call wsprintf
lea esp,[esp+12]     ;similar to ADD ESP,12 - but does not affect the flags


because you are not interested in the flags, you can use ADD ESP,12
but, LEA is a little better solution
Title: Re: program crash wsprintf
Post by: Niu on January 02, 2014, 10:41:21 PM
Many thanks dedndave,
I have understood.
but how do you get to the number 12?
Does every  push command needs 4 bytes or how did you calculate that?
Title: Re: program crash wsprintf
Post by: dedndave on January 02, 2014, 10:45:07 PM
correct, each parm is a dword, 3*4 = 12
Title: Re: program crash wsprintf
Post by: Niu on January 02, 2014, 10:46:40 PM
Thanks  :biggrin:
Title: Re: program crash wsprintf
Post by: dedndave on January 02, 2014, 10:48:21 PM
you could write it this way, if it makes more sense to you
    add     esp,3*sizeof DWORD