📜 ⬆️ ⬇️

Assembler with C ++ in Visual Studio 2013

The idea of ​​this article is not new, but since I had to spend two days analyzing all the compilation and linking errors, as well as searching for answers to my questions, I decided that Habr readers deserve to save time. Those who want to quickly learn how to use simultaneously * .asm and * .cpp files in a project, how to call C ++ methods from an assembler and vice versa, please welcome under cat.

Foreword


It all started with my reading of the publication “Assembler for Windows using Visual Studio” (hence the almost identical code). They consider using Visual Studio 2005, and for the 2013 studio, the process is similar, but there are several differences that will cause an unprepared user to search for solutions to all problems with the assembly for a long time.

Content


  1. TL; DR
  2. Project creation
  3. Setting syntax highlighting
  4. The subtleties of calling methods between C ++ and Asm
  5. application

TL; DR


For those who have absolutely no time to read: at the end of the article (in the appendix) there is a link to the finished project template and to the addon for syntax highlighting.

Project creation


Illustrated version
Turn on Visual Studio, choose File -> New -> Project ... :
')
image

Select the Win32 Console Application template, click OK :

image

Click Next :

image

Put a tick in front of the Empty project and click Finish :

image

We create source codes. To do this, right click on Source Files , select Add -> New Item ... :

image

Choose C ++ File and click Add :

image

Similarly, create a * .asm file (just change the extension in the Name field):

image

Important: the file names must be different (disregarding the extension), otherwise when creating * .obj files, there will be a problem of overwriting one object file with another .

Now settings. Make a right click on the project, select Build Dependencies -> Build Customizations ...

image

Put a tick in front of the masm and click OK :

image

Right-click on the * .asm file, select Properties ... :

image

In the Item Type field, select Microsoft Macro Assembler and click OK :

image

Choose Project -> Properties ... :

image

Choose Configuration Properties -> Microsoft Macro Assembler -> Listing File . In the Assembled Code Listing File field, enter $ (ProjectName) .lst :

image

Choose Configuration Properties -> Linker -> Advanced . In the Image Has Safe Exception Handlers field, select the value No. Click OK :

image

At this stage, the project can be considered created. Code writing is discussed in the Subtleties section of calling methods between C ++ and Asm .


Text only
Turn on Visual Studio, choose File -> New -> Project ....

Select the Win32 Console Application template, click OK .

Click Next .

Put a tick in front of the Empty project and click Finish .

We create source codes. To do this, right click on Source Files , select Add -> New Item ....

Select C ++ File and click Add .

Similarly, create a * .asm file (just change the extension in the Name field).

Important: file names must be different (not including the extension), otherwise when creating * .obj files, there will be a problem of overwriting one object file with another .

Now settings. Make a right click on the project, select Build Dependencies -> Build Customizations ...

Put a tick in front of the masm and click OK .

Right-click on the * .asm file, select Properties ...

In the Item Type field, select Microsoft Macro Assembler and click OK .

Choose Project -> Properties ...

Choose Configuration Properties -> Microsoft Macro Assembler -> Listing File . In the Assembled Code Listing File field, enter $ (ProjectName) .lst .

Choose Configuration Properties -> Linker -> Advanced . In the Image Has Safe Exception Handlers field, select the value No. Click OK .

At this stage, the project can be considered created. Code writing is discussed in the Subtleties section of calling methods between C ++ and Asm .

Setting syntax highlighting


There is an addon for Visual Studio - asmHighlighter , but at the time of this writing, there was no version for VS2013. However, after reviewing the Discussions section, I found a message from Trass3r , who, fortunately, shared the repository with the add-on version for VS2013. After installing the Visual Studio SDK, I managed to build a project and now the * .vsix package is freely available .

The subtleties of calling methods between C ++ and Asm


In order to avoid compilation and / or binding errors, remember the following:
  1. If it is necessary to call library methods from the assembler, it is sufficient to specify at the beginning of the code section which methods we are going to use.

    EXTRN printf : proc ;we'll use printf 

    Then you can simply use call :

     ;printf(ebx,eax) push eax; push ebx call printf add esp, 8 ;pop x2 
  2. If you need to call custom methods, then in addition to item 1, you must also write extern "C" before defining the method.

     extern "C" void* readName() { char* name = (char*)calloc(1, 255); scanf("%s", name); while (getchar() != '\n'); return name; } 

    Accordingly, in the * .asm file:
     EXTRN readName : proc ;and void* readName() 
    and
     call readName ;eax = readName() 

  3. In the case of using Asm-methods in C ++, it is enough just to specify the prototype:

     extern "C" { void sayHello(); } 

    This prototype corresponds to the following Asm method declaration:

     sayHello PROC call readName ;eax = readName() lea ebx, helloFormat ;ebx = &helloFormat ;printf(ebx,eax) push eax push ebx call printf add esp, 8 ;pop x2 retn sayHello ENDP 

Actually, the full source code of the example:

Source.cpp
 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> extern "C" { void sayHello(); } void main() { printf("Hello, what is your name?\n"); sayHello(); while (getchar() != '\n'); } extern "C" void* readName() { char* name = (char*)calloc(1, 255); scanf("%s", name); while (getchar() != '\n'); return name; } 


AsmSource.asm
 .686 .MODEL FLAT, C .STACK .DATA ;-----------Local data------------------------------ helloFormat BYTE "Hello, %s!", 10, 13, 0 .CODE ;-----------External usage-------------------------- EXTRN printf : proc;// we'll use printf EXTRN readName : proc;//and void* readName() ;-----------Function definitions-------------------- sayHello PROC call readName; eax = readName() lea ebx, helloFormat; ebx = &helloFormat ;printf(ebx,eax) push eax push ebx call printf add esp, 8;pop x2 retn sayHello ENDP END 



application


A complete project template can be found here .
The package for syntax highlighting asm can be found here .

PS Thank you ilynxy for fixing “deserve on”)

Source: https://habr.com/ru/post/252647/


All Articles