Can I call a C funtion in my asm code

Started by
7 comments, last by Lugerns 18 years, 10 months ago
I am not so good assembler, and i wonder if there is a way to call a c function in my asm code? Like this for exampel: int SomeThing(int i); void ChangeSign (int &A, int &B, int N) { _asm { MOV ESI, [A] MOV EDI, MOV ECX, [N] XOR EDX, EDX TEST ECX, ECX JZ SHORT L2 L1: MOV EAX, [ESI] MOV [EDI], EAX EDI = SomeThing(EDI); <- here i want to make a funtion call to a C funtion INC EDX CMP EDX, ECX JB L1 L2: } }
/Luger
Advertisement
Yes, but you'll have to make sure that you follow the calling convention of the C function. This usually involves first pushing registers on the stack so that they aren't clobbered by the function you're calling, then pushing the arguments to the function on the stack. The calling convention will determine what order you push the arguments down, but I think for C stdcall it's reverse order.
The easiest way would be:
int f(void);int g(){   asm {      // some asm code   }   int _n = f();   asm {      mov eax, _n      // more asm code   }}


Unfortunately, there is no way of controlling how the function you're calling will return the result (unless you wrote one yourself, but that's whole another story).
There is a slight possibility, that "mov eax, _n" will be optimized out, and _n won't be used at all, but honestly I doubt that any copliler would touch asm code at all.
ok, any other way to call the function?
Got any good article/link/tutorial on this subject and other asm related stuff?

/Luger
/Luger
If it's straight C linkage, then you would probably just:

call _myfunction

in assembler. This assumes that the linker will know how to resolve the _myfunction symbol. In C++ get's a little crazy with name mangling and things. You're on your own there.
If it's your function, you can declare it with __fastcall. Then you'll be sure the function would search its arguments in proper registers.
Form MSDN:
Quote:
The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left.

Then simply "call", as @smr said.
You'll find the result in eax, that's the standard.

But from my assembler practice, I think you're not supposed to mix blocks of code written in asm, with generated by compiler, at least not when the compiler cannot tell that there's a mix. And in function calls, it can't.
But I suppose the usual practice of pushing all used registers on the stack is still common, so I'd say go with it!
You need to follow the calling conventions:
http://www.angelcode.com/dev/callconv/callconv.html

Normal C functions, like float sqrt(float x), is cdecl. That means that the parameters needs to be pushed from right to left on the stack and that the return value will be in ST0 (floating point register 1) if it's a floating point value - otherwise it will be a pointer to a memory location in EAX:EDX or a value if it's <= 32 bits directly in EAX.
Killers don't end up in jailThey end up on a high-score!
Quote:Original post by smr
If it's straight C linkage, then you would probably just:

call _myfunction

in assembler. This assumes that the linker will know how to resolve the _myfunction symbol. In C++ get's a little crazy with name mangling and things. You're on your own there.


or wrap it in extern "C"

heres what I'd do in g++
extern "C"{        // ...        void Foo();}void XYZ(){        asm("# ... \n"            "call foo\n"            "# ...\n");}
ok,
thx all!

/Luger
/Luger

This topic is closed to new replies.

Advertisement