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"