|
|
|
# MASM Styleguide and Resource List
|
|
|
|
|
|
|
|
The Microsoft Assembler (MASM) is a popular assembler for Windows platforms. Unsurprisingly, there has been very few
|
|
|
|
notable projects in MASM in the last decade. Small, fast code just isn't as important as it used to be. Still, it is
|
|
|
|
a very interesting exercise to learn MASM and use it. It's difficult to get binary sizes smaller than you can with
|
|
|
|
raw assembly. Additionally, if you're in the world of reverse engineering, programming in assembly keeps your
|
|
|
|
languages consistent.
|
|
|
|
|
|
|
|
|
|
|
|
## Table of Contents
|
|
|
|
|
|
|
|
1. [Getting Started](#getting-started)
|
|
|
|
1. [The Assembler](#the-assembler)
|
|
|
|
2. [IDEs](#ides)
|
|
|
|
3. [VIM Plugins](#vim-plugins)
|
|
|
|
4. [Visual Studio Code Extensions](#visual-studio-code-extensions)
|
|
|
|
2. [Tutorials](#tutorials)
|
|
|
|
3. [Styleguide](#styleguide)
|
|
|
|
1. [Tabs vs. Spaces](#tabs-vs-spaces)
|
|
|
|
2. [Line Length](#line-length)
|
|
|
|
3. [Commenting](#commenting)
|
|
|
|
4. [Include Ordering](#include-ordering)
|
|
|
|
5. [Case Sensitivity](#case-sensitivity)
|
|
|
|
6. [Section Names](#section-names)
|
|
|
|
7. [Variable Names](#variable-names)
|
|
|
|
8. [Functions](#functions)
|
|
|
|
9. [Function Prototypes](#function-prototypes)
|
|
|
|
10. [Section](#section)
|
|
|
|
11. [Type Declarations](#type-declarations)
|
|
|
|
12. [Project Organization](#project-organization)
|
|
|
|
|
|
|
|
## Getting Started
|
|
|
|
|
|
|
|
You're going to want to get some development tools. Of course, it goes without saying you're going to need some flavor
|
|
|
|
of Windows to run this stuff. Once you've acquired Windows, you will need the assembler and an IDE (optionally).
|
|
|
|
|
|
|
|
|
|
|
|
### The Assembler
|
|
|
|
|
|
|
|
The most popular variant of MASM is [MASM32](http://www.masm32.com). It's more or less an all in one package for
|
|
|
|
coding assembly programs on Windows. One caveat - you'll need Windows 2000 or greater. This guide will focus on
|
|
|
|
MASM32 primarily. Suggestions here should be easily ported to other variants.
|
|
|
|
|
|
|
|
### IDEs
|
|
|
|
|
|
|
|
Thanks to the popularity of MASM, there are a few IDE choices if you choose to go that route. They are helpful, in that
|
|
|
|
they handle assembling and linking for you. However, it's honestly something you can handle with a script.
|
|
|
|
|
|
|
|
#### WinAsm Studio
|
|
|
|
|
|
|
|
[WinAsm Studio](http://www.winasm.net) is arguably the most popular IDE for writing assembly code on Windows
|
|
|
|
(as far as I've known). As it stands, I've had difficulty creating a new account on their forum to download the
|
|
|
|
IDE. Unfortunately, they "account wall" the download so if you can't make an account you won't get the download. It's
|
|
|
|
quite silly.
|
|
|
|
|
|
|
|
#### VisualMASM
|
|
|
|
|
|
|
|
[VisualMASM](http://www.visualmasm.com/) is another popular IDE. It's tailored to MASM and has the look and feel of
|
|
|
|
a modern IDE. The most frustrating aspect is that there's no option to create a blank project. So if you're using
|
|
|
|
a template, you're going to need to delete the base code that comes with the project to get anywhere. I have
|
|
|
|
[an issue](https://github.com/ThomasJaeger/VisualMASM/issues/5) on the VisualMASM github to address this.
|
|
|
|
|
|
|
|
### VIM Plugins
|
|
|
|
|
|
|
|
VIM has pretty good support for assembly programming out of the box. I couldn't find any plugins that made programming
|
|
|
|
any easier.
|
|
|
|
|
|
|
|
### Visual Studio Code Extensions
|
|
|
|
|
|
|
|
[x86 and x86_64 Assembly](https://marketplace.visualstudio.com/items?itemName=13xforever.language-x86-64-assembly) seems
|
|
|
|
to be the most popular extension for Visual Studio Code when it comes to developing in assembly.
|
|
|
|
|
|
|
|
## Tutorials
|
|
|
|
|
|
|
|
The most popular set of tutorials for MASM32 is [Iczelion's Tutorial Series](http://www.win32assembly.programminghorizon.com/tutorials.html).
|
|
|
|
There is a `.CHM` version of these tutorials available on the [WinAsm website](http://www.winasm.net/iczelion-tutorials.html).
|
|
|
|
|
|
|
|
## Styleguide
|
|
|
|
|
|
|
|
The styleguide is a work in progress. As I find more pretty ways to write assembly code I will put them here. I've
|
|
|
|
gathered over my time writing MASM code that every developer does things differently. This makes it incredibly
|
|
|
|
frustrating to try and read another developer's code.
|
|
|
|
|
|
|
|
_PS: It would be really cool if someone wrote a linter that checked for these things. Maybe I'll get around to it
|
|
|
|
one of these days._
|
|
|
|
|
|
|
|
### Tabs vs. Spaces
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
### Line Length
|
|
|
|
|
|
|
|
Prefer 120 characters. MASM has a hard limit of 255 characters per line according to
|
|
|
|
[this post on MASM Forum](http://www.masmforum.com/board/index.php?topic=12506.msg96273). Many times prototypes and
|
|
|
|
function invocations can have very long line lengths. For these, use `\` to split your code across multiple lines.
|
|
|
|
|
|
|
|
### Commenting
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
### Include Ordering
|
|
|
|
|
|
|
|
As a matter of style, prefer to put all `.inc` files together and all `.lib` files together. Sort them alphabetically,
|
|
|
|
and separate them by a single blank line.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
include \masm32\include\kernel32.inc
|
|
|
|
include \masm32\include\user32.inc
|
|
|
|
include \masm32\include\windows.inc
|
|
|
|
|
|
|
|
includelib \masm32\include\kernel32.lib
|
|
|
|
includelib \masm32\include\user32.lib
|
|
|
|
```
|
|
|
|
|
|
|
|
### Case Sensitivity
|
|
|
|
|
|
|
|
*Always* use the `option casemap:none` option. This prevents the assembler from thinking `MyFunction` is the same as
|
|
|
|
`myfunction`, which will save you a lot of headaches.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
.386
|
|
|
|
.MODEL flat, stdcall
|
|
|
|
option casemap:none
|
|
|
|
include \masm32\include\windows.inc
|
|
|
|
include \masm32\include\kernel32.inc
|
|
|
|
|
|
|
|
includelib \masm32\lib\kernel32.lib
|
|
|
|
|
|
|
|
.DATA
|
|
|
|
.CODE
|
|
|
|
start:
|
|
|
|
invoke ExitProcess, 0
|
|
|
|
end start
|
|
|
|
```
|
|
|
|
|
|
|
|
### Section Names
|
|
|
|
|
|
|
|
Prefer uppercase section names. This will help differentiate them from the rest of the code at a quick glance.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
.386
|
|
|
|
.MODEL flat, stdcall
|
|
|
|
option casemap:none
|
|
|
|
|
|
|
|
include \masm32\include\windows.inc
|
|
|
|
include \masm32\include\kernel32.inc
|
|
|
|
|
|
|
|
includelib \masm32\lib\kernel32.lib
|
|
|
|
|
|
|
|
.DATA
|
|
|
|
.CODE
|
|
|
|
start:
|
|
|
|
invoke ExitProcess, 0
|
|
|
|
end start
|
|
|
|
```
|
|
|
|
|
|
|
|
### Variable Names
|
|
|
|
|
|
|
|
TODO - Once this is clarified be sure to update any variable names in every section to reflect this change.
|
|
|
|
|
|
|
|
|
|
|
|
### Functions
|
|
|
|
|
|
|
|
When writing functions, indent the body of the function so it is easily differentiated from other code levels.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
WinMain proc hInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD
|
|
|
|
; Code goes here...
|
|
|
|
|
|
|
|
Ret
|
|
|
|
WinMain EndP
|
|
|
|
```
|
|
|
|
|
|
|
|
Additionally, place your functions towards the bottom of your code section. This keeps your actual code uncluttered,
|
|
|
|
and all of your functions in one easy to find place.
|
|
|
|
|
|
|
|
### Function Prototypes
|
|
|
|
|
|
|
|
In order to allow the use of functions at the bottom of your code you need to declare function prototypes above
|
|
|
|
the invoking code.
|
|
|
|
|
|
|
|
Place prototypes after all includes, and leave two empty lines between the includes and prototypes.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
include \masm32\include\kernel32.inc
|
|
|
|
include \masm32\include\user32.inc
|
|
|
|
include \masm32\include\windows.inc
|
|
|
|
|
|
|
|
includelib \masm32\include\kernel32.lib
|
|
|
|
includelib \masm32\include\user32.lib
|
|
|
|
|
|
|
|
|
|
|
|
WinMain proto :DWORD, :DWORD, :DWORD, :DWORD
|
|
|
|
```
|
|
|
|
|
|
|
|
### Function Arguments
|
|
|
|
|
|
|
|
Whether you are calling a function or writing an implementation, make sure to put a single space after each comma
|
|
|
|
delimited argument.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
WinMain proc hInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD
|
|
|
|
```
|
|
|
|
|
|
|
|
### Sections
|
|
|
|
|
|
|
|
In order to improve readability, indent the code in each section one level to differentiate it from the section name.
|
|
|
|
This makes it so, when combined with all uppercase section names, It is easier to distinguish where you are in the code.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
.CODE
|
|
|
|
start:
|
|
|
|
invoke ExitProcess, 0
|
|
|
|
end start
|
|
|
|
```
|
|
|
|
|
|
|
|
### Type Declarations
|
|
|
|
|
|
|
|
Put one space after the `:` in an argument's type declaration in order to improve readability. This goes the same
|
|
|
|
for local variable type declarations.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
```asm
|
|
|
|
WinMain proc hInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD
|
|
|
|
LOCAL wc: WNDCLASSEX
|
|
|
|
; ...
|
|
|
|
```
|
|
|
|
|
|
|
|
### Project Organization
|
|
|
|
|
|
|
|
TODO
|