简体   繁体   English

Linux内核中的asm__volatile()

[英]asm__volatile() in Linux Kernel

can somebody please explain what exactly this function is doing, I tried to google it, but found nothing: 有人可以解释一下此功能的确切作用吗,我尝试用谷歌搜索它,但是什么也没找到:

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",
);

thanks in advance for any explanation 预先感谢您的任何解释

Taking this step by step: 逐步进行以下操作:

long __res; //some variable

__asm__ volatile (
"movl $244, %%eax;"

... system calls for 32-bit x86 Linux are selected by the value in %eax . ... %eax的值选择了32位x86 Linux的系统调用。 This is the number of the get_thread_area syscall. 这是get_thread_area系统调用的编号。 See arch/x86/include/asm/unistd_32.h (in recent kernels at least) for the list of syscall numbers. 有关系统调用号的列表,请参见arch/x86/include/asm/unistd_32.h (至少在最近的内核中)。 (Note: syscall numbers are not the same between 32-bit and 64-bit.) (注意:系统调用号在32位和64位之间是不同的。)

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

... parameters to system calls are passed in registers. ...系统调用的参数在寄存器中传递。 For 32-bit x86, up to five parameters are passed in registers, in the order %ebx , %ecx , %edx , %esi , %edi (the 6th argument, for the few syscalls that need it, is passed on the user stack). 对于32位x86,最多以%ebx%ecx%edx%esi%edi的顺序在寄存器中传递五个参数(第6个参数,对于需要它的少数syscalls传递给用户)堆)。 %1 , %2 , %3 refer to the 2nd, 3rd and 4th items mentioned in the "constraints" for the inline assembler (see below). %1%2%3表示内联汇编程序在“约束”中提到的第二,第三和第四项。

(This seems slightly odd, by the way: the get_thread_area syscall only needs one argument ...) (顺便说一下,这似乎有点奇怪: get_thread_area syscall 仅需要一个参数 ...)

"int $0x80;"

... invokes the syscall. ...调用syscall。

"movl %%eax,%0"

... syscalls return a result in %eax ; ... syscalls以%eax返回结果; the %0 refers to the first item mentioned in the constraints. %0表示约束中提到的第一项。

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

... "constraints" tell gcc where it can put the input and output values that are used and produced by the inline assembler block. ...“ constraints”告诉gcc它可以将内联汇编块使用和产生的输入和输出值放在哪里。 This first section (after the first : ) is for outputs. 第一部分(在第一个: )用于输出。 "=m" here says that __res should be held in memory ( "m" ) and that it is write-only, ie any previous value will be overwritten ( "=" ). 这里的"=m"表示__res应该保留在内存中( "m" ),并且它是只写的,即任何先前的值都将被覆盖( "=" )。 Operands in constraints can be referred to by numbers in the inline assembly block (eg %0 ), starting from 0 for the first to appear. 约束中的操作数可以用内联汇编块中的数字表示(例如%0 ),从0开始第一个出现。

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

... this next section is for inputs. ...下一部分用于输入。 This says that they will all be placed in memory. 这表示它们都将被放置在内存中。

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

... this final section indicates "clobbered" registers, ie those that will be overwritten as a result of code inside the inline assembler block. ...这最后一部分指示“混乱的”寄存器,即,由于内联汇编块中的代码而将被覆盖的寄存器。 GCC will put the inline assembler block into the middle of other code that it generates, but it doesn't know what the instructions inside the block actually do - so you have to tell it that any values that may have been in those registers before the block will no longer be valid afterwards. GCC会将内联汇编器块放入它生成的其他代码的中间,但是它不知道该块中的指令实际上是做什么的-因此,您必须告诉它在该寄存器之前可能存在于那些寄存器中的任何值。此后该屏蔽将不再有效。

);

That function is performing a syscall (due to the x86 int 0x80 ). 该函数正在执行系统调用(由于x86 int 0x80 )。

The part you flagged is the GCC inline assembler helpers - which allows GCC to change the placeholders (%0-%3) to actual values as given by a C name, in this case, __res, a, b, c . 您标记的部分是GCC内联汇编器帮助程序-允许GCC将占位符(%0-%3)更改为C名称给定的实际值,本例中为__res, a, b, c

You can read about the exact inline assembler syntax here: 您可以在此处了解确切的内联汇编器语法:

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

You can find all the info you need about the gcc inline assembly syntax here: 您可以在此处找到有关gcc内联汇编语法的所有所需信息:

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

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

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