Re: question on inline assembly (kernel_thread)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 23, 2002 at 06:12:21PM +0200, Martin Maletinsky wrote:

> While studying the kernel_thread() function (2.4.8) for x86, which is written as inline assembly function, I came accross a question.

Welcome to the wierd and wacked out world of inline asm.

> 487 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
> 488 {
> 489         long retval, d0;
> 490 
> 491         __asm__ __volatile__(
> 492                 "movl %%esp,%%esi\n\t"
> 493                 "int $0x80\n\t"         /* Linux/i386 system call */
> 494                 "cmpl %%esp,%%esi\n\t"  /* child or parent? */
> 495                 "je 1f\n\t"             /* parent - jump */
> 
> .... /* Lines 496 to 501 are not relevant to my question */
> 
> 502                 "movl %3,%0\n\t"        /* exit */
> 503                 "int $0x80\n"
> 504                 "1:\t"
> 505                 :"=&a" (retval), "=&S" (d0)
> 506                 :"" (__NR_clone), "i" (__NR_exit),
> 507                  "r" (arg), "r" (fn),
> 508                  "b" (flags | CLONE_VM)
> 509                 : "memory");
> 510         return retval;
> 511 }
> 
> In the above code listing, in line 493 I understand, that this is a programmed exception having vector 128 (0x80), which is used to trigger a system call, where the system
> call is specified by the content of the eax register (from the context I guess that it should be the clone() system call, which is identified by __NR_clone).

Yep, it clones it, and looks to see if the stack has changed. If it has changed,
it is the child, and if it has not, it's the parent. If it is the parent it
returns (jumps to the 1: bit), and if it is the child it runs the thread and
then does the cleanup syscall (_exit() or so).

> What I don't understand is, how the correct system call number (__NR_clone(?)) gets into the eax register, before the programmed exception in line 493 - similar to lines

505                 :"=&a" (retval), "=&S" (d0)

This is the return values part, puts eax into retval and esi into d0 (just used
to tell the compiler esi will change)

506                 :"" (__NR_clone), "i" (__NR_exit),
507                  "r" (arg), "r" (fn),
508                  "b" (flags | CLONE_VM)

These are the input operands, the "" means put it in eax, I'd guess.. I'd write
"0", as the 0th argument in the register lists is "=&a", which says the eax
register.

"i" (__NR_exit) will put the value of the exit syscall directly in in place of
"%3" in the asm, "i" means immediate. This is because it's a macro, so it's
value may change, this is the neat way of putting it in.

Therefore, your "movl %3, %0" piece of code moves the value of __NR_exit into
eax.

509                 : "memory");

This tells gcc to reload all variables from where they were stored in memory

Hope this helps.

-- 

Mark Zealey (aka JALH on irc.openprojects.net: #zealos and many more)
mark@zealos.org; mark@itsolve.co.uk

UL++++>$ G!>(GCM/GCS/GS/GM) dpu? s:-@ a17! C++++>$ P++++>+++++$ L+++>+++++$
!E---? W+++>$ !w--- r++ !t---?@ !X---?  !R- !tv b+ G+++ e>+++++ !h++* r!-- y--
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux