繁体   English   中英

Linux内核中的asm__volatile()

[英]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内联汇编语法的所有所需信息:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM