是“asmlinkage"吗?从汇编中调用 c 函数需要吗? [英] Is "asmlinkage" required for a c function to be called from assembly?

查看:29
本文介绍了是“asmlinkage"吗?从汇编中调用 c 函数需要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个将从汇编代码调用的 C 函数.

I am writing a C function that will be invoked from assembly code.

(具体来说,我想在linux内核的系统调用处理路径中做一些检查工作,所以我会在entry_32.S中调度系统调用之前调用c函数)

(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)

在定义我的 c 函数时,我对asmlinkage"修饰符感到困惑.

I am confused with the "asmlinkage" modifier when defining my c function.

我知道 asmlinkage 是告诉编译器参数将通过堆栈传递.

I know asmlinkage is to tell the compiler that the parameters will be passed through stack.

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

问题:

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

(1) Is asmlinkage required when defining such a function that will be invoked from assembly code?

(2) gcc 中的默认调用约定是什么.如果我在定义 c 函数时省略asmlinkage",它是否意味着 _cdecl 或 fastcall?

(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) 如果默认调用约定是cdecl,为什么需要asmlinkage,考虑到cdecl 等于asmlinkage 修饰符?(我在这里正确吗?)

(3) if the default calling convention is cdecl, why is asmlinkage needed, considering cdecl is equal to asmlinkage modifier? (am I correct here?)

(4) 为什么那些系统调用函数都是用 asmlinkage 声明的.我们可以先将参数复制到寄存器中,然后调用那些系统调用函数吗?在我看来,在 x86 中,当发出系统调用时,参数很容易保存在寄存器中;那么为什么要在堆栈中保存 then 来强制通过堆栈约定传递参数呢?

(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?

最后,有人可以推荐一些我可以参考的关于这种混合汇编/c 编程的资源/书籍吗?

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) 定义这样一个将从汇编代码调用的函数时是否需要asmlinkage?

没有.实际上,fastcall 经常被使用.

No. Actually the fastcall is frequently used.

比如在entry_32.S中,搜索call",就可以得到所有从这个汇编文件中调用的c函数.然后你可以看到,许多使用 fastcall 而不是 asmlinkage 作为调用约定.例如,

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) gcc 中的默认调用约定是什么.如果我在定义一个c函数时省略了asmlinkage",它是否意味着_cdecl或fastcall?

(3) 如果默认调用约定是cdecl,那么为什么需要asmlinkage,考虑到cdecl 等于asmlinkage 修饰符?(我在这里正确吗?)

对于不是从汇编代码调用的 C 函数,我们可以安全地假设默认调用约定是 cdecl(或快速调用;没关系,因为 gcc 会负责调用者和被调用者进行参数传递.默认调用编译时可以指定约定).但是,对于从汇编代码调用的C函数,我们应该明确声明函数的调用约定,因为汇编端的参数传递代码已经固定.例如,如果将 patch_espfix_desc 声明为 asmlinkage,则 gcc 将编译该函数以从堆栈中检索参数.这与汇编端不一致,后者将参数放入寄存器中.

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.

但是我还是不清楚什么时候用asmlinkage,什么时候用fastcall.我真的需要一些指南和资源来参考.

这篇关于是“asmlinkage"吗?从汇编中调用 c 函数需要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆