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
Hi Gil,
Could you post all your source files to the board? Plus, what are your development tools?
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
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.
It shouldn't be necessary to use such names be sure you assembled the .obj file containing the function with:
{code]
.model flat,stdcall
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.
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
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.
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.
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.
Are you using LINK /DLL ?
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.
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.
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).
: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.
Quote from: hitchhikr on April 12, 2005, 04:29:52 AM
.....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).
I used 'C' instead of 'C++' so that syntax must be for 'C++' only because if I try that in 'C' I get an unresolved external reference so in plain 'C' I have to omit the "C" part and use just
extern unsigned int _stdcall TestProc(unsigned int dwValue);
Also, you don't need the double underscore, one underscore works fine.
C++ compilers can use both for backwards compatibility purposes, they usually switch to C mode whenever they're compiling a .c file and C++ mode with .cpp files.
_stdcall is just a convenient macro, the real one is __stdcall (just disable the language extensions in VC and try to compile a _stdcall function in a .c or .cpp file).
Out of curiosity, can Visual Basic also call a function from assembly? I know it can if the assembly code is a DLL but I mean in the same sense as the above C code called the assembly function.
VB uses stdcall, theorically it can since it uses ms link to create executables.
I never tried but if i had a guess i'd say that it would probably require some hacks like the modification of the vb executable that launches the linker in order to inject the .obj files into it's command line (most probably by launching a wrapper tool instead of link.exe).
I don't know about vb.net.
Ummm......I have an example of a Visual Basic program that calls a Java Class function so maybe somewhere along that same line one can use that approach to also call a MASM function or even a C function for all that matters.
Hi Robert,
That seems to be the case. Since Java compiles to byte code it is very similar to an asm object. I stopped using Visual Basic a while ago, version 3 was the last that I used. Version 3 did not create a standard 32 bit executable (PE) even though it created a windows program, so I must assume that it does so now. Bieb would probably be the one to ask about that one...
Paul