Thanks all for tolerating me so long, I've got a laundry list today... :)

1. I'm reading the Masm611 documentation, and it mentions predefined equates, like hidden@Time, hidden@Date, etc. When I try to compile this with Masm32, I get undefined symbol errors. Why? Is there a workaround? Specifically, what I was hoping to do is something like this:

Date db hidden@Date,0
Time db hidden@Time,0
Msg db "This program was built at %s on %s.",0

Buffer db 128 dup(?)

invoke wsprintf, Buffer, Msg, Time, Date
invoke StdOut, Buffer
invoke ExitProcess, 0
end start

2. What, exactly, is the difference between Masm32 and Masm 6.1x? I've heard it referred to as Masm7 and Masm32. Is it the "legitimate" (e.g. "blessed by Microsoft") successors to Masm 6, or is Masm 6 an officially (by MS) dead product, and hutch has breathed life back into it? Just curious--if the history there has a twist in it, that would explain some of the bizarre incompatibilities I'm seeing (like the inability to link 16-bit programs, ferinstance).

3. I keep reading about the ASSUME keyword in the dox. I don't need that in Win32 assy, right, since the assembler assumes everything's in one big 4Gb segment?

4. In Iczelion's tutorials, I notice that sometimes he doesn't mov an argument directly into a member of WNDCLASSEX, but rather pushes it and then pops it into the member. Example:

push hInst
pop wc.hInstance

Being curious, I changed it to a "mov wc.hInstance, hInst" and immediately got an error about operand sizes. But wc.hInstance is defined as a DWORD, and so is HINSTANCE. Mov can handle m32->r32, so I assume the problem is something to do with the fact that we're diddling with a structure. What gives?

5. In the WinAPI, the polite thing to do with, for instance, RegisterClassEx is to check the return code for zero (failure) and abort. Otherwise your app will Access Violate. The code I wrote to test for a zero return seems a little clunky to me, is there a flag set somewhere I can just check? Here's my code, tell me what you think (hey! I'm using the @@ label... I *can* be taught! :) ):

ErrRegister db "Could not register window class",0
ErrTitle db "Error",0

; (SNIP)

invoke RegisterClassEx, addr wc
;!DPB - If eax has 0, RegisterClassEx failed
cmp eax,0
jnz @F
; Error Out - couldn't register window
invoke MessageBox, NULL, addr ErrRegister, \
addr ErrTitle, MB_OK or MB_ICONERROR
mov eax, 0ffffffffh

Is that cmp really necessary?

6. I'm not out of questions, but I am out of time and want to get this posted before I go. :)

Thank you all kindly for your help,

Posted on 2002-04-21 13:51:16 by Chalain
i'll skip the masm specific questions (not using it myself ;) )

you can use assume when working with structures:

mov eax, [esi].mymember1
mov edx, [esi].mymember2
ASSUME esi: nothing

you can't move the contents of one memory location into another but have to use a register to temporarily store the value:

mov eax,hInst
mov wc.hInstance,eax

yes and no ;) on the one hand you must check the return value in eax, on the other hand you can do a 'test eax,eax' which is supposed to be faster and only needs two bytes.
Posted on 2002-04-21 14:05:38 by Tola
1) i think that those equates are used for output during assembly, and not runtime (like checking your CPU ver or echoing the time of assembly, etc)

2) i think the "diff" is Masm32 is hutch--'s package, which contains Masm6.x
Posted on 2002-04-21 14:17:03 by jademtech
masm32 v7 is not to be confused with masm 7
Posted on 2002-04-21 14:56:00 by Kudos
2) hutch should have called his package something else :), I've
seen a lot of confusion. MASM32 is basically the package maintained
by hutch, and the version numbering has nothing to do with the masm
version numbere. ml.exe is the assembler... version included in
masm32 is 6.something, the newest (with the .net release) is 7.something.

3) you don't *need* assume, except if you want to mess with SEH (then
you need ASSUME FS:NOTHING). You can also use assume when using structures
and stuff, like "assume esi ptr mystructtype" or something similar.

4) there's no memory->memory move in the x86 instruction set. I would
have used eax to transfer instead of push/pop, as that generates shorter
code and is a wee bit faster.

5) you don't *HAVE* to check for errors, but you always ought to ;).
"cmp eax, 0" works fine, "test eax, eax" is a bit shorter. Also keep
in mind that some APIs use other values to indicate errors.
Posted on 2002-04-21 16:02:09 by f0dder

MASM32 is a project that I started some years ago that uses the licencing arrangements from the old win98ddk to supply ML.EXE version 6.14 as the assembler. (IE : Read the Microsoft EULA attached to MASM32.)

The last release version of MASM from Microsoft was version 6.11. There is no version 7 of MASM.

From the XP ddk you can obtain ML.EXE version 7 and a linker that works with it, I gather that one of the later SDKs have it as well.

MASM32 is designed to build 32 bit programs only, if you want to build 16 bit software, use MASM 6.11 as it is designed for this purpose.



I actually started the project back in 1999 from memory when NO-ONE was interested in assembler and few would have known what MASM was. I named the project MASM32 so that interested people would know it was MASM in format and aimed at 32 bit production.
Posted on 2002-04-21 16:06:36 by hutch--
Well, the package naming is quite logical :), but I still it's badly
chosen... there *has* been a lot of confusion because of it :).
Posted on 2002-04-21 16:15:46 by f0dder
Msg db "This program was built at ",@CatStr(<!">,%@Date,<!"> )," on ",@CatStr(<!">,%@Time,<!"> ),0
Posted on 2002-04-21 16:26:33 by savage
hutch ...
can I use ML 7 with your package?

I've heared that masm and ml contained bugs that make them convert some instructions into a wrong binary equevalent ... is it true?

f0dder ...
when first I noticed the push pop combination I asked myself why didn't Iczelion use two mov instructions since they are faster and shorter? and is it also true that using eax is also faster than using any other register with mov instruction?
Posted on 2002-04-21 18:42:26 by code1101

MASM32 is a project that I started some years ago that uses the licencing arrangements from the old win98ddk to supply ML.EXE version 6.14 as the assembler. (IE : Read the Microsoft EULA attached to MASM32.)

Ah, okay. Thank you. MUCH clearer.

MASM32 is designed to build 32 bit programs only, if you want to build 16 bit software, use MASM 6.11 as it is designed for this purpose.

Oh, heavens no. I think a more precise statement of the value of this information to me is, now that I know I can keep myself from accidentally working on 16-bit software. :grin: I'm still at such a larval stage that I could end up getting good at 10-bit PIC assembly before I realized I'd wandered away from Win32. (Well, okay, I'd probably figure it out on or before the EEPROM burner showed up in the mail...)

Thank you all for your help.

Question about test eax, eax. A couple people say it generates "shorter" code. Are we talking about it emitting a byte or two less machine code, or running a clock faster, both, or neither? Just curious--I'm still far away from the time when saving one byte will help me. I'm writing my own get_cl right now, and I'm trying to figure out how to do it without needing 3k in the .data? section, or forcing the caller to have to remember to free an alloc'ed pointer.


Posted on 2002-04-21 19:01:40 by Chalain
code1101, I dunno why icz uses the push/pop. Ok, it doesn't
clobber the eax register, but you are usually free to use
eax as a spare, and since there's often an API call shortly
after the mem->mem moves icz does, there isn't much reason
not to use EAX.

All the registers shoule be the same speed however for some
instructions certain registers have shorter opcode encoding
which might matter a tiny little bit.
Posted on 2002-04-21 22:56:01 by f0dder
Some history about ML.exe

MASM 6.11 (This MASM is the official name that Microsoft gave their product ) was a boxed retail version of the Microsoft Macro Assembler compiler. This was a full product with manuals, linker and a lot of other tools.
It was designed at the time to run on DOS 6.22 and needed an integrated dos extender.
It was capable of generating 16 bit code linked with the included 16 bit linker, or to generate 32 bit code (for the 386,486) that needed a 32 bit linker not included.

Later, over the years Microsoft released patches to update ml.exe to 6.12, 6.13 , 6.14 and 6.15.

Each patch would add compatabilty for new processors (pentium, PII, PIII, AMD) and new instruction sets( MMX, SSE...)

Starting with 6.14 ml.exe is a full 32 bit product that no longer needs the dos extender and only runs in 32 bit consoles( W98, W2000, NT ...)

6.14 can also generate code to produce 16 bit applications. You have to assemble with the large or small model and link with the 16 bit linker.
Posted on 2002-04-23 14:03:21 by towers
Originally posted by Chalain /i]

push hInst
pop wc.hInstance

I alway use

mov wc.hInstance, 400000h

Posted on 2002-04-23 14:14:45 by bazik
You shouldn't do that, bazik. While it's true that hInstance==ImageBase
on all current win32, there's no guarantee this will be true on future
win32 versions. Also, if you're dealing with relocating code (DLLs),
you are asking for trouble :).
Posted on 2002-04-23 14:18:08 by f0dder