“asmlinkage”是必须的吗?C函数需要从汇编中调用吗?

Avatar
admin

经过数小时的研究,我得到了以下实证点:

(1) 当定义一个将从汇编代码中调用的函数时,是否需要使用asmlinkage?

不需要。实际上,fastcall经常被使用。

例如,在entry_32.S中,如果搜索“call”,您可以获得从该汇编文件中调用的所有C函数。然后您会看到,许多人使用fastcall而不是asmlinkage作为调用约定。例如,

/*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) gcc 的默认调用约定是什么?如果在定义 C 函数时省略 "asmlinkage",这是否意味着使用 _cdecl 或 fastcall?

(3) 如果默认的调用约定是 cdecl,为什么还需要 asmlinkage 呢?考虑到 cdecl 等同于 asmlinkage 修饰符,这个问题有必要吗?(我理解得对吗?)

对于从汇编代码中未调用的 C 函数,我们可以安全地假定默认调用约定为 cdecl(或 fast call;这并不重要,因为gcc将处理参数传递的调用者和被调用者。调用时可以指定默认的调用约定)。然而,对于从汇编代码中调用的 C 函数,我们应该明确声明函数的调用约定,因为汇编侧的参数传递代码已经固定。例如,如果 patch_espfix_desc 声明为 asmlinkage,则 gcc 将编译该函数以从堆栈中检索参数。这与汇编侧不一致,后者将参数放入寄存器中。

但我仍然不清楚何时使用 asmlinkage 和何时使用 fastcall。我真的需要一些指导和参考资源。