问题
In most languages, C included the stack is used for function calls. That's why you get a "Stack Overflow" error if you are not careful in recursion. (Pun not intended).
If that is true then what is so special about the asmlinkage
GCC directive.
It says, from #kernelnewbies
The asmlinkage tag is one other thing that we should observe about this simple function. This is a #define for some gcc magic that tells the compiler that the function should not expect to find any of its arguments in registers (a common optimization), but only on the CPU's stack.
I mean I don't think the registers are used in normal function calls.
What is even more strange is that when you learn it is implemented using GCC regparm function attribute on x86.
The documentation of regparm is as follows:
On x86-32 targets, the regparm attribute causes the compiler to pass arguments number one to number if they are of integral type in registers EAX, EDX, and ECX instead of on the stack.
This basically saying opposite of what asmlinkage
is trying do.
So what happens ? Are they on the stack or the registers.
Where am I going wrong ?
The information isn't very clear.
回答1:
Normally, to make calls faster (depending on the architecture), the compiler can choose to pass some parameters through registers to avoid copying them to/from the stack each time. This is particularly true for private functions that are not exported and therefore not required to obey the calling conventions defined by the ABI, in order to be further optimized.
Some ABIs actually require parameters to be passed in registers. The System V AMD64 ABI calling convention (default on Linux x86-64) is a great example of this: it dictates that function parameters should be passed through RDI, RSI, RDX, RCX, R8, R9, [XYZ]MM0–7, so the stack is very rarely used.
Now, when making a syscall in Linux, the kernel copies userspace registers on the stack in order to preserve them, and then calls the appropriate syscall function. These functions should take the parameters directly from the already saved user registers on the stack and must therefore be compiled to only and always take parameters from the stack.
In x86 32bit, the asmlinkage
macro expands to __attribute__((regparam(0)))
, which basically tells GCC that no parameters should be passed through registers (the 0
is the important part). On x86 64bit, it expands to the more specific __attribute__((syscall_linkage))
instead. The end result is the same: the function is forced to take parameters from the stack. On other architectures that always pass parameters on the stack, no special __attribute__
is even needed.
来源:https://stackoverflow.com/questions/61635931/does-asmlinkage-mean-stack-or-register