[英]asm__volatile() in Linux Kernel
有人可以解释一下此功能的确切作用吗,我尝试用谷歌搜索它,但是什么也没找到:
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",
);
预先感谢您的任何解释
逐步进行以下操作:
long __res; //some variable
__asm__ volatile (
"movl $244, %%eax;"
... %eax
的值选择了32位x86 Linux的系统调用。 这是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个参数,对于需要它的少数syscalls传递给用户)堆)。 %1
, %2
, %3
表示内联汇编程序在“约束”中提到的第二,第三和第四项。
(顺便说一下,这似乎有点奇怪: get_thread_area
syscall 仅需要一个参数 ...)
"int $0x80;"
...调用syscall。
"movl %%eax,%0"
... syscalls以%eax
返回结果; %0
表示约束中提到的第一项。
: "=m" (__res) //from here can't understand
...“ constraints”告诉gcc它可以将内联汇编块使用和产生的输入和输出值放在哪里。 第一部分(在第一个:
)用于输出。 这里的"=m"
表示__res
应该保留在内存中( "m"
),并且它是只写的,即任何先前的值都将被覆盖( "="
)。 约束中的操作数可以用内联汇编块中的数字表示(例如%0
),从0开始第一个出现。
: "m" (a), "m" (b) , "m" (c)
...下一部分用于输入。 这表示它们都将被放置在内存中。
: "%eax","%ebx","%ecx", "%edx",
...这最后一部分指示“混乱的”寄存器,即,由于内联汇编块中的代码而将被覆盖的寄存器。 GCC会将内联汇编器块放入它生成的其他代码的中间,但是它不知道该块中的指令实际上是做什么的-因此,您必须告诉它在该寄存器之前可能存在于那些寄存器中的任何值。此后该屏蔽将不再有效。
);
该函数正在执行系统调用(由于x86 int 0x80
)。
您标记的部分是GCC内联汇编器帮助程序-允许GCC将占位符(%0-%3)更改为C名称给定的实际值,本例中为__res, a, b, c
。
您可以在此处了解确切的内联汇编器语法:
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
您可以在此处找到有关gcc内联汇编语法的所有所需信息:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.