News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Another C calling question

Started by Gil, April 11, 2005, 05:46:38 PM

Previous topic - Next topic

Gil

Hi Guys,

I am stuck with C++ calling ASM.

I got help from the VC guys how to declare it in C, for example:
extern "C" void myfunc(int x);

In the ASM I program myfunc as God intended:
myfunc   proc
. . . .
myfunc   endp

This works fine, however, this calling uses __cdecl, in which the caller has to pop the arguments off the stack, very inconvenient when programming in ASM.

To prevent C++ from popping the arguments one can use stdcall:
extern "C" void __stdcall myfunc(int x);

But now the linker doesn't find myfunc.

When I look at the assembler code that C++ generates when myfunc is called:
with __cdecl  it is called as: call _myfunc
with __stdcall it is called as: call _myfunc@4

I tried to modify the myfunc name in the ASM file but nothing worked.

What's your take?

I can't get answers in a C forum as diehard C programmers get chills when talking about ASM (or any other language) :tdown

Thanks,
Gil

Vortex

Hi Gil,

Could you post all your source files to the board? Plus, what are your development tools?

Gil

Hi again

Sorry for the omission.
I am using VC++ and MASM that come with visual studio 2003 .NET.
I compile all files from the IDE.
There are no compiling erros.

I didn't post any code because the problem is not related to a specific code, just naming convention and a linker that doesn't agree with me...........

Gil

Gil

Eureka!

Sometimes posting a question helps you organize your own thoughts.
Since VC calls myfunc as _myfunc, then if it looks for _myfunc@xx I have to name it myfunc@xx
(xx is the number of bytes pushed on the stack)

End of problem.

hitchhikr

It shouldn't be necessary to use such names be sure you assembled the .obj file containing the function with:

{code]
.model flat,stdcall


Robert Collins

I have a question also about a C program calling a function in MASM.

How do you do it?

My assembly code must have a.....


start:
  '
  '
end start


If I put a 'invoke ExitProcess ,0' after the start statement then the MASM program exits immediately and my C program has no chance in calling 'myfunct'. If I omit the 'invoke ExitProcess, 0' then the assembly program terminates with an error.

If I put the function within the start.....end start statements like this:

  '
  '
.code

start:

myfunct proc
     invoke ShowMessageBox
     invoke ExitProcess,0
myfunct endp

END start

....then the assembly execution falls through into the 'myfunct' code.

I don't get it.


Robert Collins

Quote from: Gil on April 11, 2005, 05:46:38 PM
.........extern "C" void __stdcall myfunc(int x);

Maybe you should omit the "C" part and just declare your external function as

extern void _stdcall myfunc(int x);

Then in your assembly code do as hitchhikr said... 

.model flat, stdcall





GregL

Here's a good article on calling MASM procedures from C/C++:

http://www.developer.com/lang/article.php/3493531

Thanks to 'farrier' for posting the link.

tenkey

Quote from: Robert Collins on April 11, 2005, 10:07:13 PM
I have a question also about a C program calling a function in MASM.

How do you do it?

My assembly code must have a.....


start:
  '
  '
end start


Not for static linking -- if you're starting from the C main() function. [Or a Windows WinMain() function.]
If you're starting from C or C++ code, eliminate the startup stuff from the ASM code.

For a DLL, the start function is a DllEntry or DllMain function.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Robert Collins

Quote from: tenkey on April 12, 2005, 12:06:19 AM
Not for static linking -- if you're starting from the C main() function. [Or a Windows WinMain() function.]
If you're starting from C or C++ code, eliminate the startup stuff from the ASM code.

For a DLL, the start function is a DllEntry or DllMain function.

If I do that, like in the following snippit....


.486
.model flat, stdcall
option casemap :none

.code

TestProc proc dwValue:DWORD

   mov eax, dwValue
   add eax, 100
   ret

TestProc endp

end


I will get the following link errors...

LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
myasmprog.exe : fatal error LNK1120: 1 unresolved externals

I am not having a C problem, I am having an assembly problem if I omit the 'start: end start' statements.

GregL


Robert Collins

Quote from: Greg on April 12, 2005, 01:26:32 AM
Are you using LINK /DLL ?


No, it is not a DLL I am making in MASM. The snippit I posted was from that
http://www.developer.com/lang/article.php/3493531 link you posted earlier.

I already know how to call a function from an assemble DLL. I was just trying to make a simple function using MASM and then add the .obj to the 'C' program. I am not having any problems with the C program, just with the MASM program if I omit the start: end start statements and that is how it is shown in the sample from that above link.


GregL

#12
Robert,

Oh, I thought you were trying to make a DLL now, sorry.  :red

Just assemble the .asm file into an .obj file, don't link it. The error is from the linker looking for an entry point, the entry point is in the C program.

I was able to assemble the .asm file exactly as it is in the article:

.486
.model flat, stdcall
option casemap :none

.code

TestProc proc dwValue:DWORD

   mov eax, dwValue
   add eax, 100
   ret

TestProc endp

end


I had to make some small changes to the C program as follows (I'm using Pelle's C):

#include <windows.h>
#include <stdio.h>

extern unsigned int __stdcall TestProc(unsigned int dwValue);

int main(void)
{
   unsigned int dwValue  = 100;
   unsigned int dwReturn = TestProc(dwValue);

   printf("%u\n", dwReturn);
   getchar();

   return 0;
}


It works.  :bg

Sorry for the C code hutch.


hitchhikr

Quote
I will get the following link errors...

LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
myasmprog.exe : fatal error LNK1120: 1 unresolved externals

I am not having a C problem, I am having an assembly problem if I omit the 'start: end start' statements.

Use /c option in ml arguments line.
The above example is just perfect, use it as a base but just note that if you're using C++ compiler (like VC) you'll need to use this instead:


extern "C" unsigned int __stdcall TestProc(unsigned int dwValue);


to tell the compiler that TestProc is the real name of the function and to avoid the name mangling stuff (a c++ compiler would wait for a function called: TestProc@@YGII@Z).

Also in the "end blahblah" stuff "'blahblah" is just a label passed by masm to the linker to be used as an entrypoint (for an exe or a dll).

hutch--

 :bg

Greg,

Quote
Sorry for the C code hutch

We only get a little short on people who post their homework in C expecting others to translate it for them so they get their assignments done.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php