59

How do you compile assembly code using Visual Studio?

I want to compile and run an assembly source file in Visual Studio 2010.

I've created a Visual C++ project and inserted some assembly code in a file code.asm:

.586              ;Target processor.  Use instructions for Pentium class machines
.MODEL FLAT, C    ;Use the flat memory model. Use C calling conventions
.STACK            ;Define a stack segment of 1KB (Not required for this example)
.DATA             ;Create a near data segment.  Local variables are declared after
                  ;this directive (Not required for this example)
.CODE             ;Indicates the start of a code segment.

clear PROC
   xor eax, eax 
   xor ebx, ebx 
   ret 
clear ENDP 
END

However the problem is when you try and compile this, you get:

LINK : error LNK2001: unresolved external symbol _mainCRTStartup

I did go and enable the build customization masm.targets (right click project > Build Customizations..), but to no avail.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • And to *debug* asm (view registers and single-step from breakpoints) with Visual Studio: https://stackoverflow.com/questions/46394685/debugging-asm-with-visual-studio-register-content-will-not-display. See also other x86 asm links in [the x86 tag wiki](https://stackoverflow.com/tags/x86/info). – Peter Cordes Oct 13 '17 at 06:49
  • Check out my blog post [Setting Up Visual Studio 2010 For MASM32 Programming](http://scriptbucket.wordpress.com/2011/10/19/setting-up-visual-studio-10-for-masm32-programming) – Romaine Carter Oct 19 '11 at 05:20

5 Answers5

71

Sounds to me like the custom build rules for .asm files isn't enabled. Right-click the project, Custom Build Rules, tick "Microsoft Macro Assembler". With the "END clear" directive and disabling incremental linking I'm getting a clean build.

It's different starting from VS2010:

  1. Right-click Project, Build customizations, tick "masm".
  2. Right-click the .asm file, Properties, change Item Type to "Microsoft Macro Assembler".
rustyx
  • 80,671
  • 25
  • 200
  • 267
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 4
    It is on mine. Tends to be asked by programmers that use the Express edition. – Hans Passant May 27 '14 at 16:11
  • 8
    In later versions of Visual Studio (2015 for example) you have to follow this path: Project->(right click)->Build Dependencies->Build Customizations...->(check)masm – Alex May 05 '17 at 05:53
16

Command line:

Compile the code with:

ml /c /Cx /coff code.asm

You get code.obj as the output.

Link with:

link code.obj /SUBSYSTEM:console /out:go.exe /entry:clear

You can now run go.exe.

Alternatively, do it all in one go with:

ml /Cx /coff code.asm /link /SUBSYSTEM:console /link /entry:clear

Visual Studio (not solved)

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • You can edit the link line on the project's properties dialog to specify /entry:clear. /out: is specified for you automatically, as is code.obj. Assuming code.obj is assembled ok and the error is linking this should fix it. The command being run is on the advanced page of this tree. –  Dec 28 '10 at 21:29
  • The full version should be `ml /Cx /coff code.asm /link /SUBSYSTEM:console /out:go /entry:clear` not `ml /Cx /coff code.asm /link /SUBSYSTEM:console /link /entry:clear` – Dennis Ng Oct 13 '17 at 06:42
9

Visual Studio includes the MASM macro assembler. Smaller fragments of assembler code are often written in inline assembly in a C or C++ program.

To integrate an assembler file in a Visual Studio project, create a regular C/C++ project (command line or GUI), and just add a file ending in .asm to the list of source files.

To specify clear as the entry point, follow these instructions:

  1. Open the project's Property Pages dialog box. For details, see Setting Visual C++ Project Properties.

  2. Click the Linker folder.

  3. Click the Advanced property page.

  4. Modify the Entry Point property.

(It was taken from the Visual Studio documentation.)

I can confirm Hans Passant's instruction. In addition, according to this article, if you first add the "build customizations" masm checkbox, and then add the file, it will automatically be recognized as an assembler file. Furthermore, not specifying the entry point name in the END directive, but instead specifying it in the project settings also works for me.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
1

here is how to compile nasm assembly source code with vs20xx:

  1. "Excluded From Build" to "No"

  2. "Item Type" to "Custom Build Tool"

  3. Hit Apply

  4. Custom Build Tool -> General -> Command Line:

    c:\nasm\nasm -f win64 my_asm.asm

  5. Custom Build Tool -> General -> Outputs:

    my_asm.obj

  6. call the function like this:

    extern "C" int foo(void); // written in assembly!

https://www.cs.uaf.edu/2017/fall/cs301/reference/nasm_vs/

nasm tutorial:

http://cs.lmu.edu/~ray/notes/nasmtutorial/

sailfish009
  • 2,561
  • 1
  • 24
  • 31
0

The problem is that your assembly code is just a function. To compile and link, you need to have a start procedure just like Main in C/C++. You can specify the start symbol by specifying in your END directive. Like:

END clear

Or if you want, you can link the .obj file generated with the C/C++ generated .obj one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Madhur Ahuja
  • 22,211
  • 14
  • 71
  • 124
  • Since this is VC++, it must be searching a C file with Main function. The end solution would work if you are using just pure assembler and linker. – Madhur Ahuja Dec 28 '10 at 21:12
  • Actually END clear was not necessary to make it work: you simply have to specify `/entry:clear` to the linker. – bobobobo Dec 28 '10 at 21:20
  • This is another way, but if you are using pure assembler, END clear solution will work. – Madhur Ahuja Dec 28 '10 at 21:21