Q:

Assembly in Visual Studio 2013 not building even after enabling Microsoft Macro Assembler

I'm trying to run a pretty basic assembly file to do a little math and print the output, nothing challenging.  I've followed the steps given from places such as here but my build still fails and there are errors on every single line about syntax. Errors such as:
1>c:\users\damian\documents\visual studio 2013\projects\test345\test345\source.asm(22): error C2061: syntax error : identifier 'dword'
1>c:\users\damian\documents\visual studio 2013\projects\test345\test345\source.asm(24): error C2061: syntax error : identifier 'add'
1>c:\users\damian\documents\visual studio 2013\projects\test345\test345\source.asm(27): error C2061: syntax error : identifier 'pop'
1>c:\users\damian\documents\visual studio 2013\projects\test345\test345\source.asm(12): error C2061: syntax error : identifier 'main'

The code I'm trying to run is here.  I've tried changing from cpp to c compiling, I've tried setting an entry point in the linker, and I've tried right clicking on project->Build Dependencies->Build Customizations and checking masm but none of those made any difference at all.  Is there something else I'm missing?

A:

The code you tried to assemble uses NASM syntax. You need to configure Visual Studio to use NASM instead.    
1) Install NASM and add it's path to the PATH environment variable.
2) Right click on your asm file and then choose Properties->General and then choose Custom Build Tool for the Item Type field.
3) Click on Apply.
4) On the Custom Build Tool page set nasm -f win32 -o "$(ProjectDir)$(IntDir)%(Filename).obj" "%(FullPath)" for the Command Line field.
5) Set the Outputs field to $(IntermediateOutputPath)%(Filename).obj 
This will make NASM assemble your assembly source file into visual studio compatible object file.
We are not done yet though, you need to make some changes to the assembly file before you can link it using MSVC's linker.
1) MSVC's linker requires your functions to start with an underscore so main becomes _main.
2) The naming convention when declaring imported APIs is different too. So extern printf becomes extern __imp__printf
3) Call instructions to imported APIs are different too. call printf becomes call [__imp__printf]. The address of printf will be stored in an import table entry and our instruction dereferences it to find the address of printf and calls it.  
Trying to link this will also result in an error (error LNK2001: unresolved external symbol _mainCRTStartup). The way I beat this is including a c file with a dummy function that does nothing. That way, the CRT startup stub gets linked. (If there is a better method, suggest it in the comments).

