likeIT
likeIT

Reputation: 453

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

Upvotes: 2

Views: 1365

Answers (3)

Matthew Slattery
Matthew Slattery

Reputation: 46998

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. This is the number of the get_thread_area syscall. See arch/x86/include/asm/unistd_32.h (in recent kernels at least) for the list of syscall numbers. (Note: syscall numbers are not the same between 32-bit and 64-bit.)

"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). %1, %2, %3 refer to the 2nd, 3rd and 4th items mentioned in the "constraints" for the inline assembler (see below).

(This seems slightly odd, by the way: the get_thread_area syscall only needs one argument...)

"int $0x80;"

... invokes the syscall.

"movl %%eax,%0"

... syscalls return a result in %eax; the %0 refers to the first item mentioned in the constraints.

: "=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. 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, i.e. any previous value will be overwritten ("="). Operands in constraints can be referred to by numbers in the inline assembly block (e.g. %0), starting from 0 for the first to appear.

: "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, i.e. 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.

);

Upvotes: 4

jdehaan
jdehaan

Reputation: 19928

You can find all the info you need about the gcc inline assembly syntax here:

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

Upvotes: 0

Yann Ramin
Yann Ramin

Reputation: 33167

That function is performing a syscall (due to the 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.

You can read about the exact inline assembler syntax here:

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

Upvotes: 3

Related Questions