News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

WSPRINTF causes error ?

Started by BPak, April 24, 2008, 12:58:32 AM

Previous topic - Next topic

BPak

The wsprintf  function gives me an error when closing the Message box.

I must be missing something in using the WSPRINTF.

Any help appreciated!

.Const

.Data

MESSAGES DD WM_CREATE, OnCreate
DD WM_CLOSE, OnClose
DD WM_COMMAND, OnClickBtn

sCap DB 'Screen Size', 0

.Code

winMainProcedure Frame hWnd, uMsg, wParam, lParam
Mov Eax, [uMsg]
Mov Ecx, SizeOf MESSAGES / 8
Mov Edx, Addr MESSAGES
: Dec Ecx
Js >L2
Cmp [Edx + Ecx * 8], Eax
Jne <
Call [Edx + Ecx * 8 + 4]
Ret
L2: Return (FALSE)
EndF

OnCreate:
UseData winMainProcedure
;==================================
;Write the initialization code here
;==================================
Return (TRUE)
EndU

OnClose:
UseData winMainProcedure
;=========================
;Write the final code here
;=========================
Invoke IsModal, [hWnd]
Or Eax, Eax ;Cmp Eax, FALSE
Jz >
Invoke EndModal, [hWnd], IDCANCEL
Mov Eax, TRUE ;Return (TRUE)
: Ret
EndU
OnClickBtn:
UseData winMainProcedure
    Local sbuf[64]:B, cxScreen:D, cyScreen:D

Mov Eax, [wParam]
Cmp Ax, IDC_WINMAIN_BTNSCREEN
Jnz >>.exitProcedure

Shr Eax, 16
Cmp Ax, BN_CLICKED
Jnz >>.exitProcedure

    Invoke GetSystemMetrics, SM_CXSCREEN
    Mov [cxScreen], Eax

    Invoke GetSystemMetrics, SM_CYSCREEN
    Mov [cyScreen], Eax

    Invoke wsprintf, Addr sbuf, "The screen is %d pixels wide by %d pixels high.", \
     [cxScreen], [cyScreen]

    Invoke MessageBox, NULL, Addr sbuf, Addr sCap, 0

Return (TRUE)

.exitProcedure
Return (FALSE)     
EndU


BPak

Ramon Sala

Hi BPak,

In the MSDN library there is the following note:

Note: It is important to note that wsprintf uses the C calling convention (_cdecl), rather than the standard call (_stdcall) calling convention. As a result, it is the responsibility of the calling process to pop arguments off the stack, and arguments are pushed on the stack from right to left. In C-language modules, the C compiler performs this task.


High level languages and also Masm restore the stack but GoAsm does not, so you have to accomplish this task after calling wsprintf. In your code, as you pass four DWord arguments (that is, 4-byte each) to wsprintf, you have to add 16 bytes (4*4) to the Esp register like this:

    ....
    Invoke wsprintf, Addr sbuf, "The screen is %d pixels wide by %d pixels high.", \
               [cxScreen], [cyScreen]
    Add Esp, 16
    Invoke MessageBox, NULL, Addr sbuf, Addr sCap, 0
    ....



That's all!

Ramon
Greetings from Catalonia

BPak

Hi Ramon,

Quoteuses the C calling convention (_cdecl),

Thanks for the solution.  I will put that in my notes and keep look out for those _cdecl functions!

Working fine now!

BPak

Vortex

BPak,

Donkey coded a macro to call C functions, it takes care of stack balancing :

CInvoke(%Function,%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) MACRO
#IF ARGCOUNT = 11
push %9
#ENDIF
#IF ARGCOUNT > 9
push %8
#ENDIF
#IF ARGCOUNT > 8
push %7
#ENDIF
#IF ARGCOUNT > 7
push %6
#ENDIF
#IF ARGCOUNT > 6
push %5
#ENDIF
#IF ARGCOUNT > 5
push %4
#ENDIF
#IF ARGCOUNT > 4
push %3
#ENDIF
#IF ARGCOUNT > 3
push %2
#ENDIF
#IF ARGCOUNT > 2
push %1
#ENDIF
#IF ARGCOUNT > 1
push %0
#ENDIF
call %Function
#IF ARGCOUNT = 11
add esp,40
#ENDIF
#IF ARGCOUNT = 10
add esp,36
#ENDIF
#IF ARGCOUNT = 9
add esp,32
#ENDIF
#IF ARGCOUNT = 8
add esp,28
#ENDIF
#IF ARGCOUNT = 7
add esp,24
#ENDIF
#IF ARGCOUNT = 6
add esp,20
#ENDIF
#IF ARGCOUNT = 5
add esp,16
#ENDIF
#IF ARGCOUNT = 4
add esp,12
#ENDIF
#IF ARGCOUNT = 3
add esp,8
#ENDIF
#IF ARGCOUNT = 2
add esp,4
#ENDIF
ENDM


GoAsm header file set and macros by Donkey :

http://www.quickersoft.com/donkey/headers/headers.zip