MASM Assembly in Visual Studio 2010 Click to expand
Recently I have been doing some WIn32 assembly language programming, extending a simple program with some new functionality. As the program grew in length and complexity I began to miss the syntax highlighting, project management, and debugging abilities of Visual Studio.
Googling about suggesed that it was possible to get VS2010 to do what I wanted but it really wasn’t so easy to get it all set up the first time around.
In order to save myself figuring this out again, and maybe help one of you dear readers, I’m putting a step by step guide up here.
Before you start it makes a lot of sense to install support for Assembly Language Syntax Highlighting which you can find on this CodePlex project. It’s a simple download and run installer.
Step 1 : Create a clean project
File | New | Project…
Expand the ‘Other Project Types‘ tree, Select ‘Visual Studio Solutions‘, and create a new ‘Blank Solution‘.
File | Add | New Project…
Expand the ‘Other Languages‘, ‘Visual C++‘, ‘General‘ section and create a new ‘Empty Project‘
Step 2: Acquire the MASM options.
Now right click on the Project in the Solution Explorer and select ‘Build Customizations…‘
Tick the ‘masm‘ box and say OK.
Add a new file to the project with the .asm extension by right clicking on the Project in the Solution Explorer and selecting ‘Add | New Item…‘ then ‘Text File‘. Enter a filename ending with .asm (e.g. speedy.asm). Say OK.
Now (and if you skipped the last steps this won’t work) right click on the Project and select ‘Properties‘. You should see a dialog like this (Note the MASM item at the bottom of the tree). If you don’t then something went wrong.
Step 3: Configure the linker
There are a few critical things to set up in the Linker options in order to get it to work:
Set the following property to Windows or Console as appropriate
Configuration Properties > Linker > System> SubSystem
Set the entry point to the name of your main method (as per the END directive – see code)
Configuration Properties > Linker > Advanced > EntryPoint
Step 4: Write some code & Run it
.586 .model flat, stdcall option casemap :none ; To get unicode support include \masm32\macros\ucmacros.asm include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib .data ; WSTR gets you a unicode string definition WSTR wstrTitle, "Hello" WSTR wstrMessage, "World" .code main: invoke MessageBoxW, NULL, ADDR wstrMessage, ADDR wstrTitle, MB_OK invoke ExitProcess, eax end main
NOTE: Possibly the most important thing to note here is the ‘end main’ directive. This directive must be present and the name must match the label where you expect execution to kick off and the ‘EntryPoint’ we defined in step 3. Otherwise things simply won’t work.
Hit Ctrl + Shift + B to build (or use the menus etc) and it should build and run showing a simple windows message box.
Boring but proves it’s working.
Step 5: Set break points and debug it
The really cool thing is that now you can set break points and step through your code much as you are used to doing with C++ or C#
Side Note: File extensions
A small problem that you might run into is that if you move any macro definitions into their own file you need to be absolutely sure NOT to call the file .asm. If you do the linker will get horribly confused and go on and on and on about not being able to find the EntryPoint. I lost hours trying to figure that one out! Call it something .inc instead and all will be good.
The other thing is that Visual Studio seems to create a larger executable (even in release mode) than using masm on the command line. It seems to be something to do with the way it interprets the WSTR macro but I’m not 100% certain. Still if it becomes a huge issue I can always compile on the command line just before release and I get to enjoy nice debugging in the meantime.
So, there you have it. VS2010 compiling Win32 Assembler by way of the included MASM compiler.