i wrote a program in the last time. i implemented a function to show or hide a window. notice that visible was a byte (for size-saving):

;switch between SW_SHOW/SW_HIDE
xor byte ptr [visible],SW_SHOW ;SW_SHOW=0x0005, SW_HIDE=0x0000
invoke ShowWindow,hWin,visible

and what came out was:

xor byte ptr [004031C6], 05
push 00 ;since we operate w/ 32 bits a dword is pushed
mov al, byte ptr [004031C6]
movzx ax, al
push ax
push [ebp+08] ;hWin
call 00401496 ;ShowWindow

it seems as if the assembler wanted to push a word 0x0000 and then the value. but a dword 0x00000000 is pushed. in addition the value is pushed as word in ax. as you can see the stack gets messed up by 2 bytes. i wondered when i found this out...
so, is this a bug? if so, please fix it! is it fixed in masm v8?
Posted on 2003-04-15 13:50:40 by hartyl
so, is this a bug? if so, please fix it! is it fixed in masm v8?

uh... Maybe you want to talk to Bill G. about this. :grin:

BTW, did MS release MASM v8? Or, did you mean MASM32 v8?
Posted on 2003-04-15 17:09:51 by Starless
nah! i meant masm32 v8 (why sould i ask here if i didn't?)
so, is it fixed? if not, whom can i tell?
Posted on 2003-04-21 14:29:53 by hartyl
Masm is trying to promote the byte value 'visible' to a dword as specified in the ShowWindow proto. It should do this:

push word ptr 0
movzx ax, visible
push ax

The 'push 0' it generates is a dword value. This is a bug and I reported it
to MSDN several months ago.
Posted on 2003-04-21 18:48:58 by gfalen
I am a little lost here as to what is going on. In the WINDOWS.INC file the equates are defined as numbers that do not have a data size attached.

SW_HIDE equ 0
SW_SHOW equ 5

You size cast them by placing them into a function like ShowWindow(). The parameter size is DWORD for the parameter.

invoke ShowWindow,hWnd,SW_SHOW

This will generate from the prototype for ShowWindow two DWORD parameters.

If you wish to set the value prior to the use of ShowWindow(), you must observe the size set in the prototype which is DWORD.

xor byte ptr ,SW_SHOW

This is simply an error as the parameter for ShowWindow IS DWORD, not BYTE. Size saving is not an option here as ShowWindow() is determined by the code existing in the operating system and it takes the native 32 bit size parameters as normal.


Posted on 2003-04-21 20:56:32 by hutch--
From Masm32.hlp:

Syntax: INVOKE expression [,arguments]

The <invokelist> is passed to the procedure according to the types
given in that procedure's prototype. If necessary, the assembler
will generate code to convert the elements of <invokelist> to the
types specified in the prototype.

He was trying to let msm 'promote' visible to a dword. But as you can see
it is buggy and generates a 'push dword ptr 0' instead of a 'push word ptr 0'.
Posted on 2003-04-21 22:56:25 by gfalen
I don't understand. Why don't you do somethnig like

xor byte ptr [visible],SW_SHOW
movzx eax, byte ptr[visible]
invoke ShowWindow,hWin,eax
Posted on 2003-04-22 03:17:27 by roticv

As far as I understand, the extent of MASM seting the correct data type extends to determining the difference between data in the .DATA section or LOCAL variables which generates respectively the normal MOV reg, OFFSET data or for a LOCAL lea reg , data.

I have never seen it do anything like change the SIZE of the data and in fact there are macro capacities to determine the difference. Normal rule is to pass the correct data size to a procedure in accordance with the size set in the prototype.


Posted on 2003-04-22 03:45:42 by hutch--
Just look at the code posted by hartyl -

xor byte ptr [004031C6], 05 <- 'visible' - a byte
; masm tries to promote it to dword here
push 00 <- BUG - should be push word ptr 0
mov al, byte ptr [004031C6]
movzx ax, al
push ax < masm is trying to promote it to dword
push ;hWin
call 00401496 ;ShowWindow

The docs (my prev. post) say that masm will do this, but it does it incorrectly - ie. a bug!
Posted on 2003-04-22 03:58:04 by gfalen

I have seen both assemblers and compilers do unusual things in my time but with this example, just use the correct data size with the parameter and it will not happen.

Start with an error and generate other does not mean much, use the correct data size and there is no error. I understand what you refer to and it looks like MASM may have some old code in it from the 16 bit days but it no problem to avoid it, just don't force the error.

The original reference in the posting contained the error,

xor byte ptr [visible],SW_SHOW ;SW_SHOW=0x0005, SW_HIDE=0x0000

The parameters ARE DWORD in size, not WORD.


Posted on 2003-04-22 05:29:24 by hutch--
Hutch, again you're demonstrating your ignorance ^_^

Even if a DWORD value was used for the "visible" parameter, the XOR would be fine, as long as SW_SHOW is within the byterange. It's a rather silly optimization though, in my opinion.

Next, listen to what gfalen has to say. Masm is a highlevel macro assembler, and just like compiler it will (try to) convert arguments to correct sizes. Just like a 32bit C compiler will extend char/short to (32bit) int, and float to double. That it fails to do this is a bug, and if I'm not very mistaken I've seen people bitch about this more than once.
Posted on 2003-04-22 06:18:11 by f0dder

Go blow your nose and learn something. Many compilers try and fix mistakes but this IS assembler and the error is trying to use the incorrect data size. You can mess up most compilers/assemblers somewhere but you can fix the error easily by using the correct data size.

ML.EXE is a very old progeram now and while it was patched from 16 bit to 32 bit as of version 6.11d from memory, it will probably have some ancient code floating around in it somewhere so if you feed it the wrong data size in relation to the prototype, you have every chance of making a mess of it.

Simple answer is as usual in assembler, use the RIGHT data size.


Posted on 2003-04-22 08:49:38 by hutch--
Hutch, it's not about "fixing errors", it's about promoting a data type to a more natural size for the current mode of operation. (most) compilers do this, and masm appearantly does it too (or tries to).
Posted on 2003-04-22 08:56:23 by f0dder

I know where you are coming from but a compiler is a different animal, with an assembler you are supposed to know what the data size is and use the right size. Ancient ML is but some basic rules apply to any assembler, ALWAYS use the correct data size, never rely on an assembler or compiler to do this for you.


Posted on 2003-04-22 09:18:08 by hutch--
You can call it whatever you want, but masm attempts to do size extending and fails to do so properly. Imo, they ought to have flagged it as an error instead, but I guess it's okay for it to do size extension when it has a proc prototype, as it _is_ a highlevel macro assembler, and not a "raw" style assembler like debug or nasm.
Posted on 2003-04-22 09:34:41 by f0dder
*sniff* i know what i've done wrong, i know how to do it right, and i know the movzx instruction... and i know that this is a bug i reported. i just wanted to tell everybody about this...

i don't believe that constants have a specific size. if its value doesn't exceed 0xff i can use them as a byte, as i do in the example in this special case
Posted on 2003-04-22 14:07:11 by hartyl

Never mind about the discussion with f0dder, he an OK dude anyway. :tongue:

You are right that a constant does not have a specified size and it is size casted when the assembler places the value into a prototype for a function.

"push 0" is size determined at assembly time on the basis of the prototype size specifier so while the size optimisation may have been an interesting idea, no matter what, the code in the API function expects a DWORD and you can get oddities by trying to pass anything else.

You can design tricky ways of handing the different equates depending on what you wish to display but sometimes a simple approach just works better.


Posted on 2003-04-22 21:28:13 by hutch--