Can I call a C funtion in my asm code
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:
}
}
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:
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.
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
Got any good article/link/tutorial on this subject and other asm related stuff?
/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.
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:
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!
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.
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.
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");}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement