News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

program crash wsprintf

Started by Niu, January 02, 2014, 09:49:39 PM

Previous topic - Next topic

Niu

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:


dedndave

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

Niu

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?

dedndave

correct, each parm is a dword, 3*4 = 12


dedndave

you could write it this way, if it makes more sense to you
    add     esp,3*sizeof DWORD