Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 04 Aug 2003 15:15:04 -0400 (EDT)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Ryan Sommers <ryans@gamersimpact.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   RE: Assembly Syscall Question
Message-ID:  <XFMail.20030804151504.jhb@FreeBSD.org>
In-Reply-To: <20030731201227.28952.qmail@neuroflux.com>

next in thread | previous in thread | raw e-mail | index | archive | help

On 31-Jul-2003 Ryan Sommers wrote:
> When making a system call to the kernel why is it necessary to push the 
> syscall value onto the stack when you don't call another function? 
> 
> Example: 
> 
> access.the.bsd.kernel:
>  int 80h
>  ret 
> 
> func:
>  mov eax, 4    ; Write
>  call access.the.bsd.kernel
> ; End 
> 
> Works. However:
> func:
>  mov eax, 4    ; Write
>  int 80h
> ; End 
> 
> Doesn't. 
> 
> Now, if you change it to: 
> 
> func:
>  mov eax, 4    ; Write
>  push eax
>  int 80h
> ; End 
> 
> It does work. I was able to find, "By default, the FreeBSD kernel uses the C 
> calling convention. Further, although the kernel is accessed using int 80h, 
> it is assumed the program will call a function that issues int 80h, rather 
> than issuing int 80h directly," in the developer's handbook. But I can't 
> figure out why the second example doesn't work. Is the call instruction 
> pushing the value onto the stack in addition to pushing the instruction 
> pointer on? 
> 
> Thank you in advance.
> PS I'm not on the list. 

First off, why are you using asm for userland stuff?  Secondly, the kernel
assumes that all the other arguments besides the syscall to execute (i.e.
%eax) are passed on the user stack.  Thus, it has to have a set location
relative to the user stack pointer to find the arguments.  It allows for
a return IP from a call instruction to be at the top of the stack.  You
can tell this by looking at syscall() in sys/i386/i386/trap.c:

        params = (caddr_t)frame.tf_esp + sizeof(int);
        code = frame.tf_eax;
        orig_tf_eflags = frame.tf_eflags;

params is a userland pointer to the function arguments.  Adding the
sizeof(int) skips over the saved return address, or in your 3rd case,
the dummy %eax value.

-- 

John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.20030804151504.jhb>