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
- TL; DR
- Project creation
- Setting syntax highlighting
- The subtleties of calling methods between C ++ and Asm
- 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 versionTurn 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 ... :

Choose
C ++ File and click
Add :

Similarly, create a * .asm file (just change the extension in the
Name field):
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 ...
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 .
Text onlyTurn 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:
- 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
- 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()
- 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”)