RE: Assembly Syscall Question

From: John Baldwin (jhb_at_FreeBSD.org)
Date: 08/04/03

  • Next message: Rolf Grossmann: "Re: Using CVS diff to find out what has changed, including new files"
    Date: Mon, 04 Aug 2003 15:15:04 -0400 (EDT)
    To: Ryan Sommers <ryans@gamersimpact.com>
    
    

    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/
    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
    

  • Next message: Rolf Grossmann: "Re: Using CVS diff to find out what has changed, including new files"

    Relevant Pages

    • Re: Assembly Syscall Question
      ... so the stack looks like this when in the syscall ... So the kernel knows how to account for a return address to access ... So when calling the kernel directly (not through a C library ...
      (freebsd-hackers)
    • Re: Problems with FreeBSD assembly
      ... pushed onto the stack before the int 80h. ... So the extra dword pushed onto the stack takes the place of the return ... address from the function the kernel expects to have been called. ... push dword hbytes ...
      (freebsd-questions)
    • Re: Problems with FreeBSD assembly
      ... pushed onto the stack before the int 80h. ... So the extra dword pushed onto the stack takes the place of the return ... address from the function the kernel expects to have been called. ... frame. ...
      (freebsd-questions)
    • Re: How to continue debugging into kernel code?
      ... You can use SoftIce for debugging user apps in kernel more (but that not ... freeware as WinDbg). ... OTOH int 2e is for NT,W2K and not for XP anymore. ... > trap int 2E and I am able to log any Ntxxx syscall from ntdll. ...
      (microsoft.public.win32.programmer.kernel)
    • Re: Various x86 syscall mechanisms
      ... As far as I can work out, an x86_32 kernel will use "int 0x80" and "sysenter" for system calls. ... syscall interface from a 64-bit process), but will allow "sysenter", ...
      (Linux-Kernel)