Masm32: What you absolutely must know to get started
Installation
Step 1: Download the Masm32 SDK from http://masm32.com/masmdl.htm
Step 2: Open m32v11r.zip, and run install.exe - two minutes later, you will see a window Installation success
Step 3: You may or may not click "Yes" when the QEICON.VBS window pops up
Step 4: Close the small Installation is complete window
Step 5: You should read the text in the Intro.txt window
Step 6: You may install the MasmBasic package from http://masmforum.com/~masm32/board/index.php?topic=94
(all remarks in green below refer to this package, which is fully compatible with all Masm32 macros and libraries)
Step 7: After installing MasmBasic, google for Win32.hlp; it might be available at the PowerBasic tools page as Windows 32-bit API Help File.
Step 8: Install Win32.hlp and move it to \masm32\RichMasm\help\WIN32.HLP (this makes sure that F1 works in RichMasm)
Step 9: Search the web for ml.exe version 6.15, and replace the old 6.14 \masm32\bin\ml.exe
(6.14 has no SSE2; in addition, you need at least ml 6.15 to use the MasmBasic library. If you cannot find ml 6.15, use JWasm; move Jwasm.exe to \masm32\bin and use OPT_Assembler JWasm under "end start" in your source)
Step 10: Run \masm32\richmasm\richmasm.exe, and click on one of the links under Masm32 examples; press F6, and see your first Masm32 application in action. Congratulations ;-)
Optional but highly recommended for serious work:
Step 11: Go to http://www.ollydbg.de, pick the latest version, download and save as \masm32\OllyDbg\OLLYDbg.EXE. If you use MasmBasic's RichMasm editor, insert int 3 somewhere in your code, hit F6 and see Olly in action...
Hello World in Masm32 (in case you are impatient)
This is a very simple skeleton for testing your installation. Assemble, link & run it (in RichMasm: by pressing F6), or insert your first mov eax, 123 somewhere between start: and exit
--------------------------------------------------------------------------------
include \masm32\include\masm32rt.inc
.data ; initialised variables
MyAppName db "Masm32:", 0
MyReal8 REAL8 123.456
.data? ; non-initialised (i.e. zeroed) variables
MyDword dd ?
.code
start:
invoke MessageBox, 0, chr$("A box, wow!"), addr MyAppName, MB_OK
mov eax, 123
exit
end start
--------------------------------------------------------------------------------
Help and tutorials, recommended reading
|
\masm32\help\hlhelp.chm |
a must read |
|
\masm32\help\masm32.chm |
very useful, too |
|
\masm32\help\opcodes.chm |
how do mov, inc, add, sub etc work? |
|
\masm32\macros\macros.asm |
these macros will make your coding easier |
|
\masm32\RichMasm\help\WIN32.HLP |
if you saved it there, it will open in RichMasm with F1 |
|
\masm32\MasmBasic\MbGuide.rtf |
MasmBasic help file, opens in RichMasm with F1 |
|
\masm32\help\*.* |
if you find the time, study them all |
|
\masm32\include\masm32rt.inc |
will help you to understand why include \masm32\include\masm32rt.inc is enough |
|
\masm32\examples |
sample code for all occasions |
Tips, Tricks and Traps
The following is addressed to those who have experience in a high level language such as BASIC or C.
You are bound to stumble over some assembler oddities - read this section carefully.
- The "register gets trashed" trap:
Assembly beginners stumble inevitably over the phenomenon that registers "suddenly" change their values,
although there is apparently no reason for such magic changes. Here is a short explanation why.
|
eax |
accumulator |
trashable, used e.g. for returning values |
|
ebx |
base |
general purpose protected register |
|
ecx |
count |
general purpose trashable register (but protected in MasmBasic macros) |
|
edx |
data |
general purpose trashable register |
|
esi |
source index |
general purpose protected register, used e.g. in lodsd, movsd |
|
edi |
destination index |
general purpose protected register, used e.g. in stosd, scasb |
|
ebp |
base pointer |
used for handling LOCAL variables - don't touch |
|
esp |
stack pointer |
used for push & pop and passing parameters - don't touch |
* protected register (ebx, esi, edi, ebp):
1. If you use one of these registers, you must save it
on entry into a proc, and restore it before the ret
(you should avoid using ebp, as it is used for LOCAL variables; if
you use LOCALs, do not use ebp explicitly, and
do not save it)
2. an invoke GetTickCount or similar call of a Windows API will not change the protected register
* trashable register (eax, ecx, edx):
1. you can do whatever you want with this register
2. Windows will do whatever it wants with this register, so (most frequent noob error...!)
do not assume that e.g. ecx still has the same value after (for example) an invoke MessageBox, ...
3. macros of the print "Hello" type are calls to Windows APIs and will therefore trash these registers
Note that if you use only MasmBasic macros such as Open "O", #1, "MyFile.txt" or Print Str$("eax=%i", eax), the ecx register
will not be trashed; and you are not even obliged to save it.
For more detail, search Masm32 for ABI or see Register Preservation Convention in \masm32\help\asmintro.chm
- The LOCAL variables trap: They will contain garbage, so you must initialise them if you want zeroes:
MyTest proc argText:DWORD, argTitle:DWORD
LOCAL LocVarA:DWORD, LocVarB, pt:POINT, LocBuf[260]:BYTE
|
; ClearLocalVariables |
; in MasmBasic, you can clear all local variables with one instruction |
|
mov LocVarA, 0 |
; clear the first local variable |
|
and LocVarB, 0 |
; and .. 0 has the same effect but is three bytes shorter: 4 instead of 7 bytes |
|
and pt.x, 0 |
; and 0 clears the two DWORD |
|
and pt.y, 0 |
; members of the POINT structure |
|
mov LocBuf, 0 |
; a nullbyte delimits a string, so this "clears" the whole buffer |
|
invoke MessageBox, 0, argText, argTitle, MB_OK |
|
ret
MyTest endp
- The .if eax<0 trap:
This is another trap for beginners...
mov eax, -1
.if eax<0
MsgBox 0, "Eax is less than zero", "Hi", MB_OK
.else
MsgBox 0, "Surprise, surprise: eax is NOT less than zero", "Hi", MB_OK
.endif
The reason is simple: Registers are by definition unsigned integers. After a mov eax, -1, the register contains the
value 0FFFFFFFFh, decimal 4294967295 - and that is indeed a number way above zero. To achieve what you want
with .if eax<0, use .if sdword ptr eax<0 - this ensures that the register will be interpreted as a signed integer.
In MasmBasic, you can use .if signed eax<0 - the keyword signed is a simple equate for sdword ptr.
- The Console app trap
You assemble, link and run this code, and nothing happens:
include \masm32\include\masm32rt.inc
.code
start:
inkey "Masm32 is so easy!"
invoke ExitProcess, 0
end start
You try again, and the assembler complains about "fatal error: access denied"...
The reason is that if applications use e.g. print or inkey, they need a console window. The linker provides this
console window if it finds /SUBSYSTEM:CONSOLE in the command line. In some IDEs, you therefore need to use
"Console assembly and link", otherwise the application hangs. Note RichMasm autodetects whether your app
needs console or Windows mode, so simply pressing F6 ensures you get the right subsystem.
- Are 16 bits enough?
No, not really. 16 bits under Windows are obsolete. Strangely enough, some beginners still come to the Forum with 16-bit code snippets. Only if you have a compelling and absolutely plausible excuse for avoiding modern 32-bit code, search the web for masm 16-bit linker, and then go straight to the Masm 16-bit sub-forum.
- Last but not least: A few Rules for the Forum
* Use include \masm32\include\masm32rt.inc, not include C:\masm32\include\masm32rt.inc; many have installed Masm32 on a different drive, and it's a real nuisance having to replace C: with D: to test a code snippet
* To allow others to test your code, do not use environment variables for your paths. Masm32 has a hard-coded path structure, for good reasons.
* Post your complete code. Some believe that older members are eager to construct the missing headers around your snippets, but the belief is FALSE
* Formulate precise questions, provide precise error messages and error lines. You will get quicker and better answers
* Have fun with Masm, and enjoy the friendly atmosphere in the Masm32 Forum!