我认为使用asmlinkage修饰符调用函数需要将所有参数都推送到堆栈,直到我对Linux内核源代码(3.16)中的以下内容感到困惑。
来自entry_64.S link
movq %rsp,%rdi
call sync_regs
sync_regs
中arch/x86/kernel/traps.c
的定义:
asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs)
{
struct pt_regs *regs = task_pt_regs(current);
*regs = *eregs;
return regs;
}
是否需要将%rdi
/ %rsp
推送到堆叠?
答案/外卖:感谢@Jester,我在下面总结了答案:
- 注意!在x86-64上,所有参数都在寄存器中,所以这个
- 仅适用于32位内核。" [linux src comment]
答案 0 :(得分:3)
http://kernelnewbies.org/FAQ/asmlinkage表示asmlinkage
表示args总是被压在堆栈上。这可能是一个旧的文档。 32位i386 Linux在内核中使用寄存器调用约定(regparm
),asmlinkage
实际上意味着"遵循标准ABI,无论它是什么"。所以FAQ只适用于i386。
对于x86-64(以及任何其他不覆盖它的架构),asmlinkage
被定义为空,或者在c ++代码中被定义为extern "C"
。对于32位x86,它定义为regparm(0)
。 (谢谢,Jester,用于挖掘头文件。)