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
  1. The instruction set to be used (For instance .386)
  2. 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.