What is MASM?
MASM is a Macro Assembler from Microsoft (ml.exe). It has been around since the early 80's. It is a multi pass x86 assembler that produces COFF exes.
Where can I get it?
Microsoft does not sell MASM anymore, but ml does come with Visual Studio, Windows Driver Development Kit, Windows Software Development Kit. Along with ml, you will also need a linker and a few other files. I will not discuss getting the files from MS, since you will have to get and convert all the C header files and make sure you have the proper dlls. Instead I will discuss MASM32 - MASM32 contains:
link16 - 16bit linker
ml614 - 16bit vertsion
and a few more binaries. It also comes with an editor to edit your asm files, tons of examples with source, C header files converted for MASM, lib files, and the MASM32 library wich contains MANY usefull functions and source.
MASM32 also comes with poasm (macro assembler), polib (lib manager), and porc (rc to res converter) from Pelle Orinius (PellesC) http://www.smorgasbordet.com/pellesc/
Pelles' tools seem to create optimized headers and smaller exes
- Grab MAMS32 from: http://masm32.com/ run the setup, it has to be installed on a root drive i.e. c:\, e:\ NOT c:\programming or what not
- Next (a shameless plug :-P) grab MELT - Masm Error Lookup Tool which will allow you to view the error descriptions for all of the MASM tools http://www.gunnerinc.com/melt.htm
- I am an IDE guy, I like the colored text and autocomplete among other things. I use RadASM (main site seems to be down, this is the mirror) http://www.oby.ro/rad_asm/
- There is also WinASM Studio - http://www.winasm.ne...-downloads.html
- A debugger is a must- OllyDbg is a great one http://www.ollydbg.de/
- Intel and/or AMD Developers Manuals (Don't think you can get printed material anymore)
For AMD you want the "Manuals" The instruction set is in General Purpose and System Instructions
- Agner Fogs Optimization Manuals
Why MASM? When I chose Assembly MANY years ago, MASM had a large user base (read - support), tons of sample code and a prebuilt library of functions so I did not have to reinvent the wheel. Users of other Assemblers will say MASM is a HLL. Why, because of macros, invoke, if/while loops? BLAH, many of those Assemblers now have invoke and if/while loops.
There are 2 ways you can "call" functions - with invoke and with the mnuemonic call. Invoke is just a macro that makes sure the correct number of parameters are passed to the stack and also some type checking.
push NULL push NULL push offset szHello push HWND_DESKTOP call MessageBox invoke MessageBox, HWND_DESKTOP, offset szHello, NULL, NULL
Both produce the same exact code
;if/endif block .if eax == 300 ; do something for 300 here .elseif eax == 400 ; do something for 400 here .else ; neither, do something else .endif ; manual if/endif block cmp eax, 300 jne @F ; do something for 300 here jmp Done @@: cmp eax, 400 jne @F ; do something for 400 here jmp Done @@: ; neither, do something else Done:
The .if block creates the same code as the manual coded .if block above
In MASM, there are 2 important operators - ADDR and OFFSET
ADDR gets the address of a variable at runtime
OFFSET gets the address of a variable at link time
HUH?! Ok, let's explain with a little code:
.data szHello BYTE "HELLO", 0 .data? lpszHello byte 8 dup (?) .code SomeProc proc LOCAL Hello:BYTE lea esi, szHello lea edi, Hello lea ebx, lpszHello mov byte ptr [edi], 0 mov byte ptr [ebx], 0 @@: mov al, byte ptr [esi] inc esi cmp al, 0 je Done mov byte ptr [edi], al mov byte ptr [ebx], al inc edi inc ebx jmp @B Done: invoke MessageBox, NULL, addr Hello, NULL, NULL invoke MessageBox, NULL, offset lpszHello, NULL, NULL ret SomeProc endp
At runtime, the address of the Hello buffer is not known, it's address is somewhere on the stack... Behind the scenes, ADDR will do
lea eax, Hello
invoke MessageBox, NULL, addr Hello, NULL, NULL
will get assembled as:
push NULL push NULL lea eax, Hello push eax push NULL call MessageBox
ADDR uses eax to get addresses, remember that... You cannot use eax BEOFRE ADDR or you will get the error - A2133 register value overwritten by INVOKE
mov eax, 0 invoke MessageBox, eax, addr Hello, NULL, NULL
is incorrect as eax will be overwritten by ADDR
invoke MessageBox, NULL, offset lpszHello, NULL, NULL
The address of lpszHello IS known at link time since it is in the .data? section. OFFSET returns its address offset from the base starting address of your exe.
You will see code using ADDR all the time. I am against that, you should be able to look at code and know if it is a local or global variable. I only use ADDR for local variables. OFFSET for anything in the .data, .data? sections and to get the address of a proc.
This post has been edited by GunnerInc: 17 October 2011 - 04:04 PM