The MASM Forum Archive 2004 to 2012

Project Support Forums => 64 Bit Assembler => Topic started by: Terry Holmes on September 17, 2011, 08:34:56 PM

Title: Convert asm64 .c program to .cpp equivalent
Post by: Terry Holmes on September 17, 2011, 08:34:56 PM
I have a program proto.c which calls asm program test64.asm as follows

#include <windows.h>   //etc...
void test64();
__int64 *p;

int main(int argc, char* argv[] ) {
...
test64();
...
}

And the asm program starts as follows:
.code
EXTERN p:PTR SBYTE

test64 PROC
mov r9,p
....          ;etc....


When I rename the proto.c to proto.cpp I get the following compile errors--

error LNK2019: unresolved external symbol "void __cdecl testasm(void)"
error LNK2019: unresolved external symbol p

What needs to change to get this (working) program to work in c++?
Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: drizz on September 17, 2011, 09:19:32 PM
just tell it to use c name mangling

extern "C" void __cdecl testasm(void);


Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: Terry Holmes on September 17, 2011, 09:38:58 PM
Thanks that worked.
But the data sharing--variable p-- still generates unresolved external message.

Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: Terry Holmes on September 17, 2011, 10:35:42 PM
A less-than-perfect solution that seems to work is to pass the address of the array "p" into the routine as an argument:

extern "C" void __cdecl testasm(__int64 x);
__int64 p;

.
.
.
.

testasm( (int)p );

The argument arrives in the RCX register.  The asm code declarations don't seem to care what arguments are declared in the .cpp file.  MSDN confirms that RCX is reliable. 
Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: Terry Holmes on September 17, 2011, 10:37:05 PM
oops meant

__int64 *p;
Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: drizz on September 18, 2011, 03:48:25 PM
Again, use extern "c" for any shared label.

extern "C" __int64 *p;

extern p:ptr sqword


testasm( (int)p );
- chopping off pointers is not a good idea..., remember int is 32bit
- global variables are not necessary to share data, just read about win64 calling convention (arg1=rcx, arg2=rdx, etc. etc.)


/////////////////////////////////////////////
extern "C" bool test64(__int64 *data);

int main(int argc, char* argv[] ) {
__int64 *data;
   if (test64(data)) {
  }
}
/////////////////////////////////////////////
test64 proc p:ptr sqword
  ; p == rcx
 
  mov eax,1 
  ret
test64 endp


QuoteThe asm code declarations don't seem to care what arguments are declared in the .cpp file.
It's only logical that they don't. In 32bit world you have stdcall calling convention that mangles the function name with number of params at the end, for example: _test32@8 would be 2 param function.

Now further discussion depends on what assembler you are using as jwasm is a much better assembler than ml64.


Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: Terry Holmes on September 18, 2011, 04:56:05 PM
1. Am using ml64

2. Fixed   testasm( (int)p );    --to--     testasm ( (__int64)p );

3. No combination of

extern "C" __int64 *p;
-or-
__int64 *p;

with or without

extern p:ptr:sqword

in the .asm file would compile without "unresolved symbol "p" " resulting...
Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: drizz on September 19, 2011, 08:47:52 AM
Initialize the pointer.

extern "C" __int64 *p = 0;

Or you can declare p in the asm file
.data?
public p
PSQWORD typedef ptr SQWORD
p PSQWORD ? ;; extern "C" __int64 *p;

.code



OR you can dump c++ mangled name for  "__int64 *p" which is "?p@@3PEA_JEA" and use
__int64 *p; // C++
extern ?p@@3PEA_JEA:qword;; ASM
mov rax,?p@@3PEA_JEA

Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: Terry Holmes on September 19, 2011, 03:39:01 PM
Yes, the initialization worked.

extern "C" __int64 *p = 0;

Thanks drizz.  I wonder if this is documented somewhere by MS.  I would not have found it with Google.
Title: Re: Convert asm64 .c program to .cpp equivalent
Post by: drizz on September 20, 2011, 01:08:20 PM
Ok, the right way is to have two declarations, this also works for gcc(TDM-GCC-MinGW64) which otherwise gives a warning for initialized extern.

extern "C" __int64 *p;
__int64 *p;