![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Game engine designer
Join Date: May 2005
Location: Sweden
Posts: 301
Rep Power: 4
![]() |
Function call from C++ program
I am wondering how to do if I want to write functions in asm (not inline) and make calls to them from within a C++ program. The problem is how I shall tell g++ where the asmAdder() function definition is. The code looks like this:
C++ program void asmAdd();
int main()
{
asmAdd();
return 0;
}Asm function .386
.model flat, STDCALL
.code
asmAdd proc
push eax
pop eax
ret
endp asmAdd
endI got the asm function as an obj file. How do I make my C++ program compile? Thanks for your help! /Klarre |
|
|
|
|
|
#2 |
|
Game engine designer
Join Date: May 2005
Location: Sweden
Posts: 301
Rep Power: 4
![]() |
I solved the problem by myself, by using VC++ and MASM!
/Klarre |
|
|
|
|
|
#3 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Good. You merely have to link the two object files together. You must, additionally, make sure that the asm function treats the stack in the way that the C++ function expects it to. This is a matter of calling convention. In this case, with no arguments, you should be perfectly safe.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#4 |
|
Caffeinated Neural Net
![]() Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 1,031
Rep Power: 5
![]() |
A few other things you should note: First, in addition to parameter order as DaWei pointed out, you will need to pay attention to symbol naming conventions. Many C/C++ compilers for Windows and DOS prepend an underscore on non-local symbols (function names, global variables, etc), and this is what the linker looks for. If you get a message that it cannot find _asmAdd(), you should just add this underscore in your assembly source. Second, make sure your assembler is configured to generate case-sensitive symbol names, since many assemblers, by default, use case-insensitive names, or export them as all uppercase. This of course causes havoc when trying to mix code with C/C++, which are case-sensitive. Lastly, you should check your compiler docs to see what registers you can safely use. If you clobber a register that your compiler expects will hold its value from one line to the next, it can cause nasty problems in your code that can be very hard to debug. The safest approach is to push any registers onto the stack if you plan to modify them, and pop them off after, but of course this is inefficient for registers the compiler considers 'scratch registers'. However, ones like ESP, EBP, and any segment registers should generally be considered off limits. The general registers are usually safe to use (but I believe this varies with some gcc ports, so check the docs), and ESI/EDI are often used for 'register variables', so they usually need to be preserved, too.
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot. - Vaarsuvius, Order of the Stick |
|
|
|
|
|
#5 |
|
Game engine designer
Join Date: May 2005
Location: Sweden
Posts: 301
Rep Power: 4
![]() |
Thanks for your thoughts "lectricpharaoh"! I have not got any problem using the MSVC compiler and MASM. But I will remeber this when using other compilers and assmblers The code I wrote was this:
.586 .model flat, C .code asmAdder proc x:DWORD, y:DWORD fld x fmul y ret asmAdder endp end #include <iostream>
extern "C"
{
float asmAdder(float x, float y);
}
int main()
{
std::cout << asmAdder(2.0f, 5.0f) << std::endl;
return 0;
} |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|