The MASM Forum Archive 2004 to 2012

Project Support Forums => GoAsm Assembler and Tools => Topic started by: FlySky on August 27, 2011, 09:45:57 AM

Title: EXTERN "C" Calling conventions in GoASM
Post by: FlySky on August 27, 2011, 09:45:57 AM
Is there any documentation about External "C" calling conventions in GoASM.

I am playing with the following C code which I am trying to translate to use with GoASM:

// #1: XWSAStartup
extern "C"  int __stdcall XWSAStartup (WORD wVersionRequested, LPWSADATA lpWsaData) {
   lpWsaData->wVersion = 2;
   return 0;
}

I've tried using:

_XWSAStartup@8 frame wVersionRequested, lpWsaData
mov eax, [lpWsaData]
mov w[eax+WSADATA.wVersion]
xor eax, eax
ret
endf

But somehow this is not working at all. I found out about using the _xxxx@8 from a post made by Jeremy. But comparing the compiled c file with the goasm compiled in IDA they are not looking the same in anyway.

.text:10001070 ; __stdcall XWSAStartup(x, x)
.text:10001070                 public _XWSAStartup@8
.text:10001070 _XWSAStartup@8  proc near 

From the compiled C file it perfectly created the external C label. But in Goasm it simply doesn't look like that in anyway.


Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Vortex on August 27, 2011, 10:03:56 AM
Hi FlySky,

Could you try this GoAsm switch?

/ms=decorate for ms linker

Also, modify _XWSAStartup@8 to XWSAStartup
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Vortex on August 27, 2011, 10:33:34 AM
Here is an example for you :

MsgBox.asm :

.data

title   db 'Demo',0

.code

MsgBox FRAME message

    invoke  MessageBoxA,0,[message],ADDR title,0
    ret

MsgBox ENDF


Demo.cpp :



extern "C" int __stdcall MsgBox(char *message);
extern "C" int __stdcall ExitProcess(unsigned int uExitCode);


void WinMain()
{
   char *msg="GoAsm demo";
   MsgBox(msg);
   ExitProcess(0);
}


Building the project wit VC++ :

\goasm\goasm /ms MsgBox.asm
cl /Zl /c /Ogtyb2 /Gs /G6 /Gz /FoDemo.OBJ Demo.cpp
\masm32\bin\polink /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib /entry:WinMain@0 Demo.obj MsgBox.obj kernel32.lib user32.lib

Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: FlySky on August 27, 2011, 12:37:55 PM
Vortex thanks for your posts and information.

Maybe I am misunderstanding the concept of External functions.

I am playing with windows network API's atm on a small tool I made.
Basicly what I am working on is creating a wrapper dll.
The dll is created and placed in the same dir as the tool is executing from. Now it does not load the system Winsock.dll
but my wrapper dll, and that's where I am trying to use the XWSAStartup function from.
Using the C created file calling the function goes fine.
Doing it with an GoASM dll it's not working. So I assumed it had to do with the external calling.

Comparing both compiled functions:

From C

.text:10001070 ; __stdcall XWSAStartup(x, x)
.text:10001070                 public _XWSAStartup@8
.text:10001070 _XWSAStartup@8  proc near               ; DATA XREF: .rdata:off_1000C858o
.text:10001070
.text:10001070 arg_4           = dword ptr  0Ch
.text:10001070
.text:10001070                 push    ebp
.text:10001071                 mov     ebp, esp
.text:10001073                 mov     eax, 2
.text:10001078                 mov     ecx, [ebp+arg_4]
.text:1000107B                 mov     [ecx], ax
.text:1000107E                 push    offset aXwsastartup ; "XWSAStartup \n"
.text:10001083                 call    trace
.text:10001088                 add     esp, 4
.text:1000108B                 xor     eax, eax
.text:1000108D                 pop     ebp
.text:1000108E                 retn    8
.text:1000108E _XWSAStartup@8  endp

GoASM:
code:10001013
code:10001016 ; ---------------------------------------------------------------------------
code:10001016                 push    ebp
code:10001017                 mov     ebp, esp
code:10001019                 mov     eax, [ebp+0Ch]
code:1000101C                 mov     word ptr [eax], 2
code:10001021                 xor     eax, eax
code:10001023                 pop     ebp
code:10001024                 retn    8

Maybe it's the calling convention that I need to change

Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Yuri on August 29, 2011, 03:56:38 AM
From what I see, extern "C" simply undecorates the exported names.
For example, without extern "C" the exported name is "int __cdecl TestFunc(int,int)".
With extern "C" it's just "TestFunc".
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Vortex on August 29, 2011, 08:01:38 AM
Quote from: Yuri on August 29, 2011, 03:56:38 AM
From what I see, extern "C" simply undecorates the exported names.
For example, without extern "C" the exported name is "int __cdecl TestFunc(int,int)".
With extern "C" it's just "TestFunc".

Hi Yuri,

I am afraid that is not true. Disassembling Demo.obj :


.386
option dotname
.model flat

public _WinMain@0

extern _MsgBox@4: near
extern _ExitProcess@4: near

@comp.id equ 000B224FH


_data   SEGMENT DWORD PUBLIC 'DATA'

$SG272  label byte
        db 47H, 6FH, 41H, 73H, 6DH, 20H, 64H, 65H       ; 0000 _ GoAsm de
        db 6DH, 6FH, 00H                                ; 0008 _ mo.

_data   ENDS

_text   SEGMENT PARA PUBLIC 'CODE'

_WinMain@0 PROC NEAR
        push    offset $SG272
        call    _MsgBox@4
        push    0
        call    _ExitProcess@4
        ret
_WinMain@0 ENDP


As you can see, all the functions are decorated.

If you remove the "C" statements, the result will be like the following :

extern int __stdcall MsgBox(char *message);
extern int __stdcall ExitProcess(unsigned int uExitCode);


.386
option dotname
.model flat

public _WinMain@0

extern ?MsgBox@@YGHPAD@Z: near
extern ?ExitProcess@@YGHI@Z: near


This decoration type is specific to MS VC++  Other C++ compiler can have different decoration conventions.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Yuri on August 29, 2011, 09:13:09 AM
Hmm... Actually I was talking about DLLs. When I build one (in VS2008 Express) with the exported function marked as extern "C" and then look into the DLL via Dll Export Viewer, I see that the exported name is exactly the name of my function in the source code, e.g. TestFunc. If I don't use extern "C", the exported name looks like "int __cdecl TestFunc(int,int)".

Maybe I used the term "decorated" wrongly. Sorry if so.

Honestly I am not quite sure what problem FlySky is struggling with. But he said he was trying to build a wrapper DLL. So I assumed it was some issue with the names of the functions exported by that DLL.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: FlySky on August 29, 2011, 05:52:14 PM
Yuri and Vortex thanks for the replies so far.
I've included the GoASM source and the C-compiled DLL.

The thing is the following, using the C-compiled DLL the program is able to communicate properly with it.
Using the GoASM project it can't communicate properly with it.
Since the C-compiled dll (test1 function) is using the EXTERN "C" decoration I was assuming that was the problem.
As when comparing both DLL's in IDA, the C-compiled DLL is nicely generating an export while GoASM doesn't.
So the question was how would I be able to do the same in GoAsm what the C-compiled version looks like.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: donkey on August 29, 2011, 06:44:23 PM
Hi Flysky,

I haven't had much time to look at your problem but I have also had fits when using C libraries. I've had some success with the /mix switch for GoLink.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Vortex on August 29, 2011, 07:08:19 PM
Quote from: FlySky on August 29, 2011, 05:52:14 PM
Since the C-compiled dll (test1 function) is using the EXTERN "C" decoration I was assuming that was the problem.

Hi FlySky,

EXTERN "C" is a bit confusing here as your source code is C and not C++   The EXTERN "C" statement is specific to C++ if I am not wrong.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: wjr on August 29, 2011, 07:46:52 PM
Remove the space and use "EXPORT:5332" as well as omitting the ":NONAME" part, since that will not include the function for export by name in the DLL (only by ordinal). How about this...


EXPORT:5332
XWSAStartup FRAME wVersionRequested, lpWsaData
;
;
ENDF
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: Yuri on August 30, 2011, 02:49:11 AM
You can decorate the name manually in GoAsm source:

export _test_1@8 FRAME param1, param2
    mov eax,1
    ret
ENDF


But the problem may be the wrong calling convention, since the FRAME directive is intended for Windows callback functions, which use stdcall, while your C DLL probably uses cdecl. To do this in GoAsm, you have to write your functions without FRAMEs.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: GregL on September 02, 2011, 12:55:00 AM
Quote from: VortexThe EXTERN "C" statement is specific to C++ if I am not wrong.

Vortex is correct. You don't need extern "C" with C.  It is used with C++ to undecorate mangled names.
Title: Re: EXTERN "C" Calling conventions in GoASM
Post by: FlySky on October 01, 2011, 09:10:49 AM
Quote from: wjr on August 29, 2011, 07:46:52 PM
Remove the space and use "EXPORT:5332" as well as omitting the ":NONAME" part, since that will not include the function for export by name in the DLL (only by ordinal). How about this...


EXPORT:5332
XWSAStartup FRAME wVersionRequested, lpWsaData
;
;
ENDF


Sorry for the later reply. The issues is perfectly fixed using what WJR suggested. I didn't find this in GoASM documentation though. Exporting by ordinals fixed the problems. Thanks for all suggestion guys.