Introduction to MASM
A few years ago I got into assembler a bit, did some research on how to compile MASM (Microsoft Macro Assembler) code as well as learning the language itself. However, only a few weeks later I lost my interest in it and continued on with my life...
Déjà-vu
However, recently I wanted to do some work in assembler again, however it took me quite some time to setup an IDE for the assembler (MASM) and I also had to google a lot about the behaviour of MASM. It was something I had already done years ago when I first worked with assembler.
This made me think about how I could avoid this from happening again and I suddenly realized that I got a blog ready for my input so why not use it? Basically I want to have this article contain the setup as well as some basic non-obvious MASM stuff so I can use it as a cheat sheet in the future – If I ever get into assembler programming again.
Visual Studio with AsmHighlighter
First of all, the IDE setup was not as hard as I thought. Just install Visual Studio and use a plugin called AsmHighlighter. When you’re done doing that, you can simply create an empty C++ project in Visual Studio, right click the project and select Custom build rules. On the new window activate masm. From now on, you can simply create new empty text files and rename them to .asm in order to let them be noticed by the compiler. However, in order to successfully build the project you also need to specify a target subsystem (For instance /SUBSYSTEM:CONSOLE
) as well as the entry point of your application (In the project properties under Linker » Advanced).
MASM structure
Before you continue, I want to make it clear that this is not meant to be an assembler tutorial – there are enough internet resources out there for that. I just wanted to go a little bit into the non-obvious MASM basics.
The basic layout of a MASM-file contains some information at the beginning of the file:
.386
.model flat, stdcall
- The instruction set to be used (For instance
.386
) - The memory model as well as the calling convention to be used (For instance
.model flat, stdcall
)
However, as soon as you want to use functions of the WinAPI you also need to include the following statement:
option casemap:none
This will let symbol names be case sensitive – which is needed in order to properly access the WinAPI-functions.
Segments
The Microsoft Macro Assembler basically consists of a variety of different segment types, the most used are .code
and .data
. Code segments contain executable code and data segments allocate space for variables of your program.
A basic example
This is a small code example for a basic application that does basically nothing:
.386 .model flat, stdcall
option casemap:none
ExitProcess proto uExitCode:DWORD
.code
main:
invoke ExitProcess, 0
end main
In fact this program is not as basic as it may seem, besides the parts we already talked about we also define a label (In this case main
). With the end
directive we determine the end of our module and we’re also telling the assembler where to find the entry point of our module using a parameter.
However, we also declare the prototype of a WinAPI function (In this case ExitProcess
) and we also invoke this function.
Procedures
MASM has a very easy way of creating and calling procedures and functions. We already saw how to invoke a procedure (Using the invoke
statement), however the assembler also allows us to define our own procedures. This is quite similar to the proto
statement we already used in order to declare the ExitProcess
prototype:
AddNumbers proc numberA:DWORD, numberB:DWORD
mov eax, numberA
add eax, numberB
AddNumbers endp
In this case we declared a procedure that takes two 4-byte arguments (DWORDs) and returns the sum of those. (On a side note, the stdcall calling convention specifies that the eax
register should contain the return value)
Includes
The last topic I wanted to talk about are includes. As you can do in C++ programs, you can include other files in assembler as well. You can simply use the include
directive followed by the file name. For example:
include defines.inc
As you can see, this statement will include a defines.inc file that relies in the same folder as the current file.
There’s also the includelib
directive in order to include .lib files. For example:
includelib masm32libmsvcrt.lib
This example uses the MASM32 SDK. The SDK is very useful, however I wasn’t able to compile them without errors yet.
Epilogue
This article only showed you some of the MASM basics that I just wanted to point out, however in order to really get started with MASM I can recommend to look for some tutorials on the interwebz - There's quite a selection out there.