ASM functions in c
ASM functions in c
Hey guys
What do i need to do in order to get a function in assembler to be able to be called from c. By this i mean how do i declare them in c
do i just do extern _function ?
Peter
What do i need to do in order to get a function in assembler to be able to be called from c. By this i mean how do i declare them in c
do i just do extern _function ?
Peter
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ASM functions in c
your asm function must be declared global in the asm file ... then you have to declare the prototype of the function in a C header.
i strongly suggest your ASM function only return pointers or integers (do not return structures as it means other calling conventions) -- and same rule apply for parameters.
Code: Select all
-=-=-=-=-= 8< -=-= ASM =-=-=-=-
global _my_func
_my_func:
push ebp
mov ebp,esp
; your asm code here
; [ebp+8] == first C parameter, [ebp+12]=second,
; [ebp+16] == third ...
mov eax,<return code>
pop ebp
ret
-=-=-=-=-= 8< -=-=- C -=-=-=-=-=-
int my_func(...);
Re:ASM functions in c
Hmm whenever i try and call my ASM funtions it crashes the program.
do i need to have
global _name
_name:
or
global _name
name:
Also how can i get the ASM to be put inline or does this happen automatically. If not will defining my function as inline in teh c header file do it.
Peter
do i need to have
global _name
_name:
or
global _name
name:
Also how can i get the ASM to be put inline or does this happen automatically. If not will defining my function as inline in teh c header file do it.
Peter
Re:ASM functions in c
This is what you do:
Int your asm source file put
Function is the name of your function.
Then in your C source file put a prototype that looks something like this:
Replace it with the return type of your function & the args of your function.
Int your asm source file put
Code: Select all
[GLOBAL _Function]
Then in your C source file put a prototype that looks something like this:
Code: Select all
extern void _Function(int args);
Re:ASM functions in c
Hey,
Sorry i did some typos: where i said Int i meant in.
And one more thing:
When you put Before your function in your asm file, just put it at the top.
After you do the prototype, use the function as a normal 'c' function!!
Ciao
Sorry i did some typos: where i said Int i meant in.
And one more thing:
When you put
Code: Select all
[GLOBAL _Function]
After you do the prototype, use the function as a normal 'c' function!!
Ciao
Re:ASM functions in c
Sorry, i forgot to say something:
When you do the prototype you don't need to put the underscore (_) so just put something like this
Cya, that's all i have to say!!
When you do the prototype you don't need to put the underscore (_) so just put something like this
Code: Select all
extern void Function(void);
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ASM functions in c
what do you mean by "crash" ? a reboot at run-time ? This should not occur unless you have trashed some registers that the C code expects to be saved/restored by the callee ...pskyboy wrote: Hmm whenever i try and call my ASM funtions it crashes the program.
You need to know that C/C++ compilers splits the register set in two parts :
- registers saved by the caller (mainly %eax and %edx)
- registers saved by the callee (mainly every other registers)
it is therefore wise to put a pusha / popa pair around your code so that you're sure you did not trash anything ... (though it might makes more complicated to set a return value in %eax with that technique...)
Now, another possible reason why your code crash is that you did something wrong with the stack (pushed something you don't pop or pop something you didn't push), which leaves the stack inconsistent state at the time of executing the RET instruction
A way you can protect yourself from this is to use
Code: Select all
push ebp
mov ebp, esp
...
mov esp,ebp
pop ebp
ret
this is that ^ one ... a typo from mine ... note that the leading underscore is only mandatory if you have a DOS/windows-based system: the ELF file format used in Linux do not prepend a '_' to the function names ...do i need to have
global _name
_name:
by no way the compiler will be able to inline an ASM function written in stuff.asm into a C function written in other_stuff.cAlso how can i get the ASM to be put inline or does this happen automatically. If not will defining my function as inline in teh c header file do it.
Mainly because the compiler completely ingore what is in stuff.asm by the time it writes other_stuff.o ...
If you want your ASM function to be inlined, you need to declare it as a
Code: Select all
static __inline__ fct( <args> )
Code: Select all
asm __volatile__ ("<code>" : <registers use & arguments passing)
oh . i'm afraid i assumed you use GCC in the latest (__inline__ and __volatile__) hints. of course those ones are compiler-specific (better not use them with VC++
Re:ASM functions in c
You assumed right i am using GCC
My code that crashes the program is
[glogal _read_cr0]
_read:
mov eax, cr0
retn
This was taken from a tuitorial on bona fide OS dev
Oh and when i say crash it causes the system to be reset
Peter
My code that crashes the program is
[glogal _read_cr0]
_read:
mov eax, cr0
retn
This was taken from a tuitorial on bona fide OS dev
Oh and when i say crash it causes the system to be reset
Peter
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ASM functions in c
this should not crash the system in a correct environment ...
you're facing an "obscure event"
i suspect there is something with about your stack, or about the way nasm handled the "retn" instruction (maybe you could disassemble your file using "objdump -d [.o file] > [.dis file]" and check if the opcodes are the one expected ...
i guess "_read" instead of "_read_cr0" is a typo ... however, the linker should not let you go ahead if _read wasn't defined ... maybe you can disassemble the calling function and see if the address for the call is the right one as well (once the whole file has been linked and is ready for loading ...)
you're facing an "obscure event"
i suspect there is something with about your stack, or about the way nasm handled the "retn" instruction (maybe you could disassemble your file using "objdump -d [.o file] > [.dis file]" and check if the opcodes are the one expected ...
i guess "_read" instead of "_read_cr0" is a typo ... however, the linker should not let you go ahead if _read wasn't defined ... maybe you can disassemble the calling function and see if the address for the call is the right one as well (once the whole file has been linked and is ready for loading ...)
Re:ASM functions in c
inline volatile static int cr0(){
int a;
asm(
"movl %%cr0, %0\n\t"
: "=a" (a)
);
return a;
}
int a;
asm(
"movl %%cr0, %0\n\t"
: "=a" (a)
);
return a;
}
Re:ASM functions in c
Perhaps you does something wrong with the extern-statement. It should look something like this:
extern long _read_cr0();
In this case, gcc knows that the eax register will be changed after the function-call. If the type of the return value is void (no return value), gcc uses eax before the function is called and afterwards it assumes that eax has the same value like before. So you must save eax in a function that returns nothing. The code for your asm-function looks like this:
This way works in nasm and gcc. I compile/assemble both files to their object file and link these two object files to one binary.
Another thing is that there is no need to name your asm-function with a beginnig underscore ( _read_cr0 ). it can also have normal names like C-funktions ( read_cr0 ).
If it still doesn't work you should try to declare a asm-function that does nothing else than return back. It this also trashes your PC the problem isn't the way you call your function but the addressing of your function (the call instruction generated by gcc doesn't jump (call) to the right offset of your function).
I hope I could help you!
extern long _read_cr0();
In this case, gcc knows that the eax register will be changed after the function-call. If the type of the return value is void (no return value), gcc uses eax before the function is called and afterwards it assumes that eax has the same value like before. So you must save eax in a function that returns nothing. The code for your asm-function looks like this:
Code: Select all
;asm-file
[global _read_cr0]
;some other asm-code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; long _read_cr0(); ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_read_cr0:
mov eax, cr0
ret
;....
Code: Select all
//C-file
//include ....
extern long _read_cr0();
//other c-stuff
//some dummy-function (only to demonstrate it)
void dummy(int para1, int para2)
{
long temp; //a local variable
//...
//now we need cr0
temp = _read_cr0();
//now we have cr0 in temp
}
Another thing is that there is no need to name your asm-function with a beginnig underscore ( _read_cr0 ). it can also have normal names like C-funktions ( read_cr0 ).
If it still doesn't work you should try to declare a asm-function that does nothing else than return back. It this also trashes your PC the problem isn't the way you call your function but the addressing of your function (the call instruction generated by gcc doesn't jump (call) to the right offset of your function).
I hope I could help you!
Re:ASM functions in c
These are my C declarations for the same code
extern "C" inline unsigned int read_cr0();
extern "C" inline void write_cr0(unsigned int);
extern "C" inline unsigned int read_cr3();
extern "C" inline void write_cr3(unsigned int);
extern "C" inline void jump(unsigned int);
extern "C" inline unsigned int read_cr0();
extern "C" inline void write_cr0(unsigned int);
extern "C" inline unsigned int read_cr3();
extern "C" inline void write_cr3(unsigned int);
extern "C" inline void jump(unsigned int);
Re:ASM functions in c
Got it working
LOL, my kernel had become bigger then 512bytes and i was onyl loading in 1 sector so it was cutting the ASM code linked on the end off.
Peter
LOL, my kernel had become bigger then 512bytes and i was onyl loading in 1 sector so it was cutting the ASM code linked on the end off.
Peter
Re:ASM functions in c
__inline__ static int cr0(){
int a;
asm(
"movl %%cr0, %0\n\t"
: "=a" (a)
);
return a;
}
int main(){
return cr0();
}
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 50 push eax
00000004 50 push eax
00000005 0F20C0 mov eax,cr0
00000008 83E4F0 and esp,byte -0x10
0000000B 89EC mov esp,ebp
0000000D 5D pop ebp
0000000E C3 ret
0000000F 90 nop
C:\DOCUME~1\ADMINI~1.BDJ\Desktop\NEWFOL~1>gcc -O2 -c test.c
C:\DOCUME~1\ADMINI~1.BDJ\Desktop\NEWFOL~1>ld --oformat=binary --entry=_main --Ttext=0x0 -o test.bin test.o
C:\DOCUME~1\ADMINI~1.BDJ\Desktop\NEWFOL~1>ndisasmw -b32 test.bin > test.txt
int a;
asm(
"movl %%cr0, %0\n\t"
: "=a" (a)
);
return a;
}
int main(){
return cr0();
}
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 50 push eax
00000004 50 push eax
00000005 0F20C0 mov eax,cr0
00000008 83E4F0 and esp,byte -0x10
0000000B 89EC mov esp,ebp
0000000D 5D pop ebp
0000000E C3 ret
0000000F 90 nop
C:\DOCUME~1\ADMINI~1.BDJ\Desktop\NEWFOL~1>gcc -O2 -c test.c
C:\DOCUME~1\ADMINI~1.BDJ\Desktop\NEWFOL~1>ld --oformat=binary --entry=_main --Ttext=0x0 -o test.bin test.o
C:\DOCUME~1\ADMINI~1.BDJ\Desktop\NEWFOL~1>ndisasmw -b32 test.bin > test.txt
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:ASM functions in c
Hehe ... i knew this was an environment problempskyboy wrote: LOL, my kernel had become bigger then 512bytes and i was onyl loading in 1 sector so it was cutting the ASM code linked on the end off.