Taylor Bockman
7 years ago
committed by
GitHub
1 changed files with 241 additions and 0 deletions
@ -0,0 +1,241 @@ |
|||||||
|
# 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 |
Loading…
Reference in new issue