Illustrated Guide

How to Link NASM Assembly Code into Microsoft Visual C++ 2008

On Windows, Microsoft Visual C++ is the standard compiler. Visual C++ 2008 "Express Edition" is free for download directly from Microsoft (400MB).  Visual C++ has a pretty nice inline assembly syntax, but for big chunks of assembly it's easier to use NASM, the Netwide Assembler.  Here's how to use NASM from Visual C++ 2008:
  1. Download NASM for Windows.  Unzip it to a location of your choice.  I'm calling it "C:\yourdir" below.
  2. Open Visual C++, and make a normal Win32 project.  Add C++ files all you like.
  3. In Notepad, create an assembly language file, with the ".asm" filename extension.  Be sure to declare your function name "global", and put an underscore in front of all external functions, including your own.  Below, I'm defining a function called "foo" in C++, but Windows will link to the name "_foo".   Similarly, I'm calling the C function "printf", but the name is "_printf" in Windows assembly.
  4. Drag the assembly file into your project.
  5. Tell Visual C++ how to build the assembly file, using NASM:
        - Right-click on the assembly file
        - Choose "Properties":
    Right click, and choose "Properties"
        - Open "Custom Build Step"
        - Choose "General"
        - Enter in "Command Line": c:\yourdir\nasm -f win32 -o test.obj $(InputPath)
        - Enter in "Outputs": test.obj
        - Press "OK"
    Code properties dialog box
  6. Finally, build and run normally!  Be sure to extern "C" your assembly function prototype from C++!
Here's a little example with C++ and assembly source files, living together happily in a single Visual C++ project (200KB).  I've included nasm.exe 2.05 (linked above) in the zip file so you should be able to easily build this example in Visual C++ 2008.

Bonus: Avoiding __imp__printf crash from Microsoft Inline Assembly

When called from the Microsoft Visual C++ 2008 inline assembler, by default printf crashes horribly inside some random function called "__imp__printf".  This even happens in this Microsoft example code.

You can fix the crash by linking with a different runtime library: the "Multi-Thread Debug" (/MD), not "Multi-Thread Debug DLL" library (/MDd in the command line).  Right-click on the C++ source file, choose "Properties", "C/C++", "Code Generation", and "Runtime Library".  The non-DLL versions work fine with inline assembly.  The DLL versions crash, and they're the default.  I don't know why they crash, but they do, even with Microsoft example code.  Go Windows!
Choosing a Runtime Library

O. Lawlor,
Up to: Class Site, CS, UAF