I am writing a C function that will be invoked from assembly code.
(Specifically, I want to do some checking job in the path of system call handling in linux kernel, so I will call the c function before a system call is dispatched in entry_32.S)
I am confused with the "asmlinkage" modifier when defining my c function.
I know asmlinkage is to tell the compiler that the parameters will be passed through stack.
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
Questions:
(1) Is asmlinkage required when defining such a function that will be invoked from assembly code?
(2) what is the default calling convention in gcc. If I omit "asmlinkage" when defining a c function, does it imply _cdecl or fastcall?
(3) if the default calling convention is cdecl, why is asmlinkage needed, considering cdecl is equal to asmlinkage modifier? (am I correct here?)
(4) why are those system call functions all declared with asmlinkage. Can we copy the parameters to registers first, then call those system call functions? From my point of view, in x86, when issuing a system call, the parameters are readily saved in registers; then why bother to save then in stack to enforce such passing parameters via stack convention?
Finally, can anybody recommend some resources/books that I can refer to for such mix assembly/c programming?
After several hours' research, I got the following empirical points:
(1) Is asmlinkage required when defning such a function that will be invoked from assembly code?
No. Actually the fastcall is frequently used.
For example, in entry_32.S, if you search "call", you can obtain all the c functions invoked from this assembly file. Then you can see, many use fastcall instead of asmlinkage as the calling convention. For example,
/*in entry_32.S*/
movl PT_OLDESP(%esp), %eax
movl %esp, %edx
call patch_espfix_desc
/*in traps_32.c*/
fastcall unsigned long patch_espfix_desc(unsigned long uesp,
unsigned long kesp)
(2) what is the default calling convention in gcc. If I omit "asmlinkage" when defining a c function, does it imply _cdecl or fastcall?
(3) if the default calling convention is cdecl, why is asmlinkage needed, considering cdecl is equal to asmlinkage modifier? (am I correct here?)
For C functions not invoked from assembly code, we can safely assume the default calling convention is cdecl (or fast call; it doesn't matter, because gcc will take care of the caller and callee for parameter passing. The default calling convention can be specified when compiling). However, for C functions invoked from assembly code, we should explicitly declare the function's calling convention, because the parameter passing code in assembly side has been fixed. For example, if patch_espfix_desc is declared as asmlinkage, then gcc will compile the function to retrieve parameters from stack. This is inconsistent with the assembly side, which put the parameters into registers.
But I am still not clear when to use asmlinkage and when to use fastcall. I really need some guideline and resources to refer to.