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/