<br><br><div class="gmail_quote">On Thu, Sep 8, 2011 at 5:28 PM, Pei Lin <span dir="ltr">&lt;<a href="mailto:telent997@gmail.com">telent997@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5">2011/9/8 rohan puri &lt;<a href="mailto:rohan.puri15@gmail.com">rohan.puri15@gmail.com</a>&gt;:<br>
&gt;<br>
&gt;<br>
&gt; On Thu, Sep 8, 2011 at 12:47 PM, Pei Lin &lt;<a href="mailto:telent997@gmail.com">telent997@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; 2011/9/8 rohan puri &lt;<a href="mailto:rohan.puri15@gmail.com">rohan.puri15@gmail.com</a>&gt;:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; On Thu, Sep 8, 2011 at 9:50 AM, Mulyadi Santosa<br>
&gt;&gt; &gt; &lt;<a href="mailto:mulyadi.santosa@gmail.com">mulyadi.santosa@gmail.com</a>&gt;<br>
&gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Hi :)<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; On Thu, Sep 8, 2011 at 10:40, rohan puri &lt;<a href="mailto:rohan.puri15@gmail.com">rohan.puri15@gmail.com</a>&gt;<br>
&gt;&gt; &gt;&gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt; Hi Mulyadi,<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; Thanks for the response. I do agree with the issue concerning the<br>
&gt;&gt; &gt;&gt; &gt; no.of<br>
&gt;&gt; &gt;&gt; &gt; registers available are less for 32 bit to that of 64 bit.<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; But even in this case if parameters are more than the no of register<br>
&gt;&gt; &gt;&gt; &gt; for<br>
&gt;&gt; &gt;&gt; &gt; 32<br>
&gt;&gt; &gt;&gt; &gt; bit, then also before executing int 80h interrupt it stores the<br>
&gt;&gt; &gt;&gt; &gt; parameters<br>
&gt;&gt; &gt;&gt; &gt; in the register and after that system call dispatcher puts them on<br>
&gt;&gt; &gt;&gt; &gt; the<br>
&gt;&gt; &gt;&gt; &gt; kernel stack of that process. So, how the case where more than no of<br>
&gt;&gt; &gt;&gt; &gt; registers are the parameters to the system call is handled.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Please don&#39;t top post :)<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Regarding passing the parameters when it is more than number of<br>
&gt;&gt; &gt;&gt; registers used in x86 32 bit, AFAIK it&#39;s using EDX to contain the<br>
&gt;&gt; &gt;&gt; address of user space memory that contains the data, later it will be<br>
&gt;&gt; &gt;&gt; copied to kernel stack IIRC.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; --<br>
&gt;&gt; &gt;&gt; regards,<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Mulyadi Santosa<br>
&gt;&gt; &gt;&gt; Freelance Linux trainer and consultant<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; blog: <a href="http://the-hydra.blogspot.com" target="_blank">the-hydra.blogspot.com</a><br>
&gt;&gt; &gt;&gt; training: <a href="http://mulyaditraining.blogspot.com" target="_blank">mulyaditraining.blogspot.com</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Sorry for top posting. :)<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Got it now. Thanks.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Regards,<br>
&gt;&gt; &gt; Rohan.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt; Kernelnewbies mailing list<br>
&gt;&gt; &gt; <a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
&gt;&gt; &gt; <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; Kernel newbies website crashed? can not login, only get the snapshot as<br>
&gt;&gt; below.<br>
&gt;&gt; <a href="http://kernelnewbies.org/FAQ/asmlinkage" target="_blank">http://kernelnewbies.org/FAQ/asmlinkage</a><br>
&gt;&gt;<br>
&gt;&gt; FAQ/asmlinkage<br>
&gt;&gt; What is asmlinkage?<br>
&gt;&gt; The asmlinkage tag is one other thing that we should observe about<br>
&gt;&gt; this simple function. This is a #define for some gcc magic that tells<br>
&gt;&gt; the compiler that the function should not expect to find any of its<br>
&gt;&gt; arguments in registers (a common optimization), but only on the CPU&#39;s<br>
&gt;&gt; stack. Recall our earlier assertion that system_call consumes its<br>
&gt;&gt; first argument, the system call number, and allows up to four more<br>
&gt;&gt; arguments that are passed along to the real system call. system_call<br>
&gt;&gt; achieves this feat simply by leaving its other arguments (which were<br>
&gt;&gt; passed to it in registers) on the stack. All system calls are marked<br>
&gt;&gt; with the asmlinkage tag, so they all look to the stack for arguments.<br>
&gt;&gt; Of course, in sys_ni_syscall&#39;s case, this doesn&#39;t make any difference,<br>
&gt;&gt; because sys_ni_syscall doesn&#39;t take any arguments, but it&#39;s an issue<br>
&gt;&gt; for most other system calls. And, because you&#39;ll be seeing asmlinkage<br>
&gt;&gt; in front of many other functions, I thought you should know what it<br>
&gt;&gt; was about.<br>
&gt;&gt;<br>
&gt;&gt; It is also used to allow calling a function from assembly files.<br>
&gt;&gt;<br>
&gt;&gt; There also have explicit explanation in the kernel maillist archive.<br>
&gt;&gt; Date:   Sat, 18 Jun 2005 16:29:01 +0200<br>
&gt;&gt; To: Roy Lee &lt;<a href="mailto:roylee17@gmail.com">roylee17@gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Sat, 18 Jun 2005 22:00:39 +0800<br>
&gt;&gt; Roy Lee &lt;<a href="mailto:roylee17@gmail.com">roylee17@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt; It says that &quot;To tell a compiler not to use the argument in the<br>
&gt;&gt; &gt; registers&quot;. but the syscall&#39;s argument does pass the arguments though<br>
&gt;&gt; &gt; registers, doesn&#39;t it?<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; yes, user space programs put arguments in registers (ebx, ecx, edx...) but<br>
&gt;&gt; see what happens later...<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; 1) user space programs do something like this:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; mov $SYSCALLNUMER, %eax<br>
&gt;&gt; mov $ARG1, %ebx<br>
&gt;&gt; mov $ARG2, %ecx<br>
&gt;&gt; ...<br>
&gt;&gt; int $0x80 ------ go to kernel syscall handler ---&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; ---&gt; arch(i386/kernel/entry.S:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; ....<br>
&gt;&gt;        # system call handler stub<br>
&gt;&gt; ENTRY(system_call)<br>
&gt;&gt;        pushl %eax # save orig_eax<br>
&gt;&gt;        SAVE_ALL<br>
&gt;&gt;        GET_THREAD_INFO(%ebp)<br>
&gt;&gt;                                        # system call tracing in operation<br>
&gt;&gt;        /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw<br>
&gt;&gt; and not testb<br>
&gt;&gt;  */ testw<br>
&gt;&gt; $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp) jnz<br>
&gt;&gt; syscall_trace_entry cmpl $(nr_syscalls), %eax<br>
&gt;&gt;        jae syscall_badsys<br>
&gt;&gt; syscall_call:<br>
&gt;&gt;        call *sys_call_table(,%eax,4)<br>
&gt;&gt;        movl %eax,EAX(%esp) # store the return value<br>
&gt;&gt; ...<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; notice just these 2 things:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; 1) SAVE_ALL ---&gt; it&#39;s a MACRO that do this:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; #define SAVE_ALL \<br>
&gt;&gt;        cld; \<br>
&gt;&gt;        pushl %es; \<br>
&gt;&gt;        pushl %ds; \<br>
&gt;&gt;        pushl %eax; \<br>
&gt;&gt;        pushl %ebp; \<br>
&gt;&gt;        pushl %edi; \<br>
&gt;&gt;        pushl %esi; \ ....<br>
&gt;&gt;        pushl %edx; \ &gt; ARG3 &lt;<br>
&gt;&gt;        pushl %ecx; \ &gt; ARG2 &lt;<br>
&gt;&gt;        pushl %ebx; \ &gt; ARG1 &lt;<br>
&gt;&gt;        movl $(__USER_DS), %edx; \<br>
&gt;&gt;        movl %edx, %ds; \<br>
&gt;&gt;        movl %edx, %es;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; 2) call *sys_call_table(,%eax,4)<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; this calls the &quot;C&quot; system call function<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; So, since the arguments are passed on the stack (see SAVE_ALL) the &quot;C&quot;<br>
&gt;&gt; function MUST take them from the stack.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; Best Regards<br>
&gt;&gt; Lin<br>
&gt;<br>
&gt; Hi Lin,<br>
&gt;<br>
&gt; Thanks for the information. :)<br>
&gt;<br>
&gt; One thing regarding that asmlinkage FAQ, does the author means process<br>
&gt; kernel stack when he indicates the usage of CPU stack?<br>
&gt;<br>
&gt; Also in file,<br>
&gt; arch/x86/include/asm/linkage.h : -<br>
&gt;<br>
&gt; /*<br>
&gt;  * Make sure the compiler doesn&#39;t do anything stupid with the<br>
&gt;  * arguments on the stack - they are owned by the *caller*, not<br>
&gt;  * the callee. This just fools gcc into not spilling into them,<br>
&gt;  * and keeps it from doing tailcall recursion and/or using the<br>
&gt;  * stack slots for temporaries, since they are live and &quot;used&quot;<br>
&gt;  * all the way to the end of the function.<br>
&gt;  *<br>
&gt;  * NOTE! On x86-64, all the arguments are in registers, so this<br>
&gt;  * only matters on a 32-bit kernel.<br>
&gt;  */<br>
&gt;<br>
&gt; This comment states that it only happens for 32-bit arch and for 64 - bit<br>
&gt; arch parameters are kept in registers itself.<br>
&gt;<br>
&gt; Thats why for system_call assembly function, for 32-bit this SAVE_ALL method<br>
&gt; is used and for 64-bit this SAVE_ALL method is not used.<br>
</div></div>Yes, x86-64 expand the general-purpose registers from 8 to 16<br>
The main features include:<br>
  Pointers and long integers are 64 bits long. Integer arithmetic<br>
operations support 8, 16, 32, and 64-bit<br>
data types.<br>
  The set of general-purpose registers is expanded from 8 to 16.<br>
  Much of the program state is held in registers rather than on the<br>
stack. Integer and pointer procedure<br>
arguments (up to 6) are passed via registers. Some procedures do not<br>
need to access the stack at all.<br>
  Conditional operations are implemented using conditional move<br>
instructions when possible, yielding<br>
better performance than traditional branching code.<br>
  Floating-point operations are implemented using a register-oriented<br>
instruction set, rather than the<br>
stack-based approach supported by IA32.<br>
<br>
more information as below link:<br>
<a href="http://www.cs.cmu.edu/%7Efp/courses/15213-s07/misc/asm64-handout.pdf" target="_blank">http://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf</a><br>
<br>
<br>
&gt;<br>
&gt; Regards,<br>
&gt; Rohan.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
<br>
<br>
<br>
--<br>
Best Regards<br>
<font color="#888888">Lin<br>
</font></blockquote></div><br>Yes  agreed, Thanks. :)<br>