调用关于asmlinkage的约定

时间:2015-08-10 13:28:13

标签: assembly linux-kernel x86-64 calling-convention

我认为使用asmlinkage修饰符调用函数需要将所有参数都推送到堆栈,直到我对Linux内核源代码(3.16)中的以下内容感到困惑。

来自entry_64.S link

 movq %rsp,%rdi
 call sync_regs

sync_regsarch/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]
  •   

1 个答案:

答案 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,用于挖掘头文件。)