The MASM Forum Archive 2004 to 2012

Specialised Projects => Compiler Based Assembler => Assembler With Microsoft Visual C => Topic started by: Vortex on August 26, 2006, 10:12:08 AM

Title: Calling C++ functions from MASM
Post by: Vortex on August 26, 2006, 10:12:08 AM
Here is a simple example of calling a decorated C++ function from MASM.  The problem with C++ functions is that they have a complicated decoration scheme. An easy way to solve the problem is to look at the assembly listing produced by the C++ compiler. Of course, you can use a tool like dumpbin to view the decorated symbols :

\masm32\bin\dumpbin /SYMBOLS sum.obj

Microsoft (R) COFF Binary File Dumper Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file sum.obj

File Type: COFF OBJECT

.
.
008 00000000 SECT3  notype ()    External     | ?sum@@YGHHH@Z (int __stdcall sum(int,int))
.
.

The example project :

.386
.model flat, stdcall
option casemap :none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc
include     \masm32\include\masm32.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\masm32.lib

?sum@@YGHHH@Z PROTO SYSCALL

sum EQU <pr2 PTR ?sum@@YGHHH@Z>


.data
format1 db  '10 + 20 = %d',0
x       dd  10
y       dd  20

.data?
buffer  db  100 dup(?)

.code

start:

    invoke  sum,x,y
    invoke  wsprintf,ADDR buffer,ADDR format1,eax
    invoke  StdOut,ADDR buffer
    invoke  ExitProcess,0

END start


Sum.cpp ( C++ source file compiled with VC++ Express 2005 ) :


int __stdcall sum(int x , int y)
{
  return(x+y);
}


Building the project :

cl /c /Oty2 /Zl /Gs /GS- /FoSum.obj /Fa Sum.cpp
\masm32\bin\ml /c /coff Sumtest.asm
\masm32\bin\polink /SUBSYSTEM:CONSOLE Sumtest.obj Sum.obj

[attachment deleted by admin]
Title: Re: Calling C++ functions from MASM
Post by: ToutEnMasm on August 26, 2006, 12:51:11 PM
Hello,
Dumpbin is certainly useful for other purpose.
Protolib give (in comment) the Full translation of the decorated name.Including the type of call and the parameters.That is more useful to call a function.
                                      ToutEnMasm

               
Title: Re: Calling C++ functions from MASM
Post by: Vortex on August 26, 2006, 09:10:18 PM
ToutEnMasm,

The problem here is not to undecorate a function but to find the decorated form as you need to write the prototype correctly so you can call the C++ function from your asm module :

?sum@@YGHHH@Z PROTO SYSCALL
Title: Re: Calling C++ functions from MASM
Post by: GregL on August 27, 2006, 02:27:45 AM
Vortex,

Thanks for this good information.  :U  I had never mixed MASM and C++ before, I had only mixed MASM with C.

Why PROTO SYSCALL? I wouldn't have thought it was that.

Title: Re: Calling C++ functions from MASM
Post by: GregL on August 27, 2006, 05:39:47 AM
Vortex,

I fiddled around with your example this evening. It got it to work including the C Run-Time Library <stdio.h> on the C++ side, but as soon as I included the C++ Standard Library <iostream> on the C++ side, things really got to be a mess. I never did get it to work.  :dazzled:  I got it to build but it would crash on execution. It's crashing in 'ostream'.

Title: Re: Calling C++ functions from MASM
Post by: zooba on August 27, 2006, 06:16:56 AM
You can also use the extern "C" directive to export undecorated names.


Greg,

C++ uses special syntax for streams, perhaps this is causing issues. I don't actually have an installation of C++ here so I can't check.

Cheers,

Zooba :U
Title: Re: Calling C++ functions from MASM
Post by: Vortex on August 27, 2006, 08:22:51 AM
Hi Greg,

Normally, the PROTO statement puts a leading underscore to the external functions. This is valid for STDCALL and C functions as they are decorated with a leading underscore : _ExitProcess@4

In our case, ?sum@@YGHHH@Z is exported without the underscore. So, to avoid the symbol appearing in the front of the function, we use the SYSCALL convention.

Looking at the assembly output of the compiler , sum.asm :

.model flat

.
.

PUBLIC ?sum@@YGHHH@Z

.
.


Zooba is right here, the special syntax of C++ can cause some errors. Greg, can you send your project here?
Title: Re: Calling C++ functions from MASM
Post by: GregL on August 27, 2006, 06:45:14 PM
Vortex,

Thanks for the explanation.

Attached is the project after I modified it. I was using ML 6.15, VC++ 6.0 and MS Link 6.0.


zooba,

Thanks for the tip.



[attachment deleted by admin]
Title: Re: Calling C++ functions from MASM
Post by: Vortex on August 27, 2006, 07:04:55 PM
Hi Greg,

Thanks for the example but it crashes on my Win XP HE SP2   Is there way to rebuild it with VC++ Express 2005?
Title: Re: Calling C++ functions from MASM
Post by: GregL on August 27, 2006, 07:10:35 PM
Vortex,

Sure, I will make a copy of the project and switch to ML 8.0, VC++ 2005 and MS Link 8.0. I'll attach it when I'm done.

later:
It doesn't crash, it just gracefully exits. I get the same acess violation in the same spot in the debugger.



[attachment deleted by admin]
Title: Re: Calling C++ functions from MASM
Post by: drizz on August 27, 2006, 07:55:58 PM
entrypoint is in asm code (main), hence the crt startup code is excluded,
hence the funcions that depend on that initialization crash.

move the entrypoint to cpp code.
Title: Re: Calling C++ functions from MASM
Post by: GregL on August 27, 2006, 08:36:09 PM
drizz,

Ah, thanks. 

duh.  :red





Title: Re: Calling C++ functions from MASM
Post by: Vortex on December 17, 2010, 07:23:41 PM
Another method is to use Agner Fog's objconv tool to rename the complex function ?sum@@YGHHH@Z to the more simple _sum@8 :

objconv -fcoff -nr:?sum@@YGHHH@Z:_sum@8 Sum.obj Sum2.obj