I have come upon a weird problem with call wsprintf with invoke. Perhaps I'm only doing something wrong here, but when I use a WORD for argument in wsprintf,
and use invoke,
the compiler produce code like this to push the value:



push 0
push word ptr TheNumber


And push 0 is the opcode 6a00 which pushes a DWORD, 00000000.
So the whole program crash, because the stackpointer gets messed up and wsprintf fails somehow.

=(((((((

It should be like this to work,



push word ptr 0
push word ptr TheNumber


I did a testprogram, please check it, and correct if I'm wrong,
because I really need to push words and use invoke, I don't want to handcode the calls to wsprintf.

Am I doing something wrong in the invoke? Hope I'm not doing something terribly wrong...




.486
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data

szMes db "Number1:%#X",13,10,"The_String:%s",13,10,"Number2:%#X",0

number1 dw 505h
The_String db "Hello there.",0
number2 dw 0FFFFh


szCaption db "testing wsprintf",0

.data?

szBuffer db 256 dup (?)

.code

start:

; This will produce right result

push word ptr 0
push number2
push OFFSET The_String
push word ptr 0
push number1
push OFFSET szMes
push OFFSET szBuffer

call wsprintf
add esp,4*5
invoke MessageBoxA, NULL, addr szBuffer, addr szCaption, MB_OK

; This will produce wrong result, and crash the program

invoke wsprintf, addr szBuffer, addr szMes, number1, addr The_String, number2

invoke MessageBoxA, NULL,addr szBuffer,addr szCaption,MB_OK

invoke ExitProcess,0

end start
Posted on 2002-09-28 20:59:06 by david
Hi,



invoke wsprintf, addr szBuffer, addr szMes, number1, The_String, number2


should be



invoke wsprintf, addr szBuffer, addr szMes, number1, addr The_String, number2
Posted on 2002-09-28 21:02:36 by roticv
Yes I just saw it when posting , I corrected that typo, it makes no difference though.
The problem still remains as I described it above.
Posted on 2002-09-28 21:22:08 by david
MASM should assemble the short form: 66h, 6Ah, 00h -- to push an immediate byte of zero. It looks like MASM is broken here - I'd just load the words into registers for pushing (MOVZX reg, WORD PTR mem). :(
Posted on 2002-09-28 22:44:21 by bitRAKE
What about changing word to dword, that should fix the problem?

However i do not know why there is a need to push 0 or rather push word ptr 0
Posted on 2002-09-29 03:33:26 by roticv
THis is a known MASM bug of invoke. Very strangely it occurs only with unsigned numbers. So if you def?ne


number1 SWORD 505h

it may work
Posted on 2002-09-30 01:47:55 by japheth
[size=9].486

.model flat,stdcall
option casemap:none

include \dev\masm32\include\windows.inc
include \dev\masm32\include\kernel32.inc
include \dev\masm32\include\user32.inc

includelib \dev\masm32\lib\kernel32.lib
includelib \dev\masm32\lib\user32.lib

.data

szMes db "Number1:%#X",13,10,"The_String:%s",13,10,"Number2:%#X",0

number1 dw 505h
[color=blue]db 0, 0 ;or simply dw 0[/color]
The_String db "Hello there.",0
number2 dw 0FFFFh
[color=blue]db 0, 0 ;or simply dw 0[/color]
[color=red]number3 dw 999h ;Added, to test if it reads this address.[/color]



szCaption db "testing wsprintf",0

.data?

szBuffer db 256 dup (?)

.code

start:

; This will produce right result

push word ptr 0
push number2
push OFFSET The_String
push word ptr 0
push number1
push OFFSET szMes
push OFFSET szBuffer

call wsprintf
add esp,4*5
invoke MessageBoxA, NULL, addr szBuffer, addr szCaption, MB_OK

; This will produce right result

invoke wsprintf, addr szBuffer, addr szMes, [color=blue]DWORD PTR [number1][/color], addr The_String, [color=blue]DWORD PTR [number2][/color]

invoke MessageBoxA, NULL,addr szBuffer,addr szCaption,MB_OK

invoke ExitProcess,0

end start[/size]
Remember normal stack alignment is 4.
Posted on 2002-09-30 02:15:45 by stryker