【问题标题】:asm__volatile() in Linux KernelLinux 内核中的 asm__volatile()
【发布时间】:2011-07-31 04:17:31
【问题描述】:

有人能解释一下这个函数到底在做什么吗,我试图用谷歌搜索它,但什么也没找到:

long __res; //some variable

__asm__ volatile (
"movl $244, %%eax;"
"movl %1, %%ebx;"
"movl %2, %%ecx;"
"movl %3, %%edx;"
"int $0x80;"
"movl %%eax,%0"
: "=m" (__res) //from here can't understand
: "m" (a), "m" (b) , "m" (c)
: "%eax","%ebx","%ecx", "%edx",
);

提前感谢您的任何解释

【问题讨论】:

    标签: c gcc x86 linux-kernel inline-assembly


    【解决方案1】:

    一步一步来:

    long __res; //some variable
    
    __asm__ volatile (
    "movl $244, %%eax;"
    

    ... 32 位 x86 Linux 的系统调用由 %eax 中的值选择。这是get_thread_area 系统调用的编号。请参阅arch/x86/include/asm/unistd_32.h(至少在最近的内核中)以获取系统调用号列表。 (注意:系统调用号在 32 位和 64 位之间是不同的。)

    "movl %1, %%ebx;"
    "movl %2, %%ecx;"
    "movl %3, %%edx;"
    

    ... 系统调用的参数在寄存器中传递。对于 32 位 x86,最多可以在寄存器中传递五个参数,顺序为 %ebx%ecx%edx%esi%edi(第 6 个参数,用于少数需要它的系统调用,在用户堆栈上传递)。 %1%2%3指的是内联汇编的“约束”中提到的第2、3、4项(见下文)。

    (顺便说一句,这似乎有点奇怪:get_thread_area 系统调用only needs one argument...)

    "int $0x80;"
    

    ...调用系统调用。

    "movl %%eax,%0"
    

    ... 系统调用在%eax 中返回结果; %0 指的是约束中提到的第一项。

    : "=m" (__res) //from here can't understand
    

    ...“约束”告诉 gcc 它可以将内联汇编程序块使用和生成的输入和输出值放在哪里。第一部分(在第一个 : 之后)用于输出。 "=m" 这里说__res 应该保存在内存中("m")并且它是只写的,即任何以前的值都将被覆盖("=")。约束中的操作数可以通过内联汇编块中的数字来引用(例如%0),从 0 开始第一个出现。

    : "m" (a), "m" (b) , "m" (c)
    

    ...下一部分用于输入。这表示它们都将被放入内存中。

    : "%eax","%ebx","%ecx", "%edx",
    

    ...这最后一部分表示“被破坏的”寄存器,即由于内联汇编程序块内的代码而将被覆盖的寄存器。 GCC 会将内联汇编程序块放入它生成的其他代码的中间,但它不知道块内的指令实际上是做什么的 - 所以你必须告诉它在这些寄存器中可能存在的任何值之前块之后将不再有效。

    );
    

    【讨论】:

    • 非常感谢您的回答,只有一个关于破坏寄存器的问题,我的 GCC 会在覆盖之前保存它们吗?
    • @likeIT:是的,如果需要,GCC 会自己保存它们。
    【解决方案2】:

    该函数正在执行系统调用(由于 x86 int 0x80)。

    您标记的部分是 GCC 内联汇编程序助手 - 它允许 GCC 将占位符 (%0-%3) 更改为 C 名称给出的实际值,在本例中为 __res, a, b, c

    您可以在这里阅读准确的内联汇编语法:

    http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

    【讨论】:

      【解决方案3】:

      您可以在此处找到有关 gcc 内联汇编语法的所有信息:

      http://www.ibm.com/developerworks/linux/library/l-ia.html

      【讨论】:

        猜你喜欢
        • 2017-04-08
        • 1970-01-01
        • 2010-09-28
        • 2010-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-15
        • 2016-04-05
        相关资源
        最近更新 更多