OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [sys/] [go32/] [setstack.S] - Rev 1773

Go to most recent revision | Compare with Previous | Blame | View Log

/*  This routine potentially increases the stack size at runtime based on
    the _stklen variable.  Only used by DPMI code.
    Copyright (c) 1993  C. Sandmann
    Environment:  called by crt0.s (and gcrt0.s)
                  EAX, EBX, EBP, EDI, ESI disposable (cleared on return) */

        .text
        .globl  __setstack
__setstack:
        movl    %esp,%eax
        andl    $0xc0000000,%eax        /* clear all except upper bits */
        jne     ok_stack                /* obviously not DPMI! */
        movw    %ss,%ax
        lsll    %eax,%ebx               /* stack segment limit */
        movl    %esp,%eax               /* current location */
        subl    %ebx,%eax               /* Free stack */
        cmpl    %eax,__stklen
        jb      ok_stack

/* Not enough stack.  Call sbrk() to get a new area.  Copy current ESP + 20
   to end of new area (3 args + our stack).  Change ESP to new area.  Set new
   limit to start of new area using DPMI services.  */

        pushl   __stklen
        call    _sbrk                   /* eax = got memory base */
        popl    %ebx                    /* remove _stklen */
        cmpl    $0xffffffff,%eax        /* if eax = -1 failure */
        je      badstack
        addl    %eax,%ebx               /* ebx now is end of new stack area */
        andl    $0xfffffff0,%ebx        /* 16 byte alignment */
        addl    $0xfff,%eax             /* make stack base page aligned */
        andl    $0xfffff000,%eax        /* 4096 byte alignment */

/* Now copy old stack to new stack.  We only need our part + 4 words, 3 for
   the parameters to pass to main, one for our return EIP (4 extra safety) */
        movl    %esp, %esi              /* Source is current stack */
        subl    $0x20, %ebx             /* 8 longwords */
        movl    %ebx, %edi              /* Destination is new stack */
        movl    $8,%ecx
        rep
        movsl

/* New stack in place.  Change ESP to point to it.  Assumes new stack is
   higher in memory so we don't get caught by limit.  Change limit using 
   DPMI services. */

        movl    %ebx,%esp               /* Switch to new stack */
        subl    $1,%eax                 /* Low 12 bits all 1s */
        pushl   %eax                    /* Easiest way to move long to words */
        popw    %dx
        popw    %cx
        movl    $8,%eax                 /* DPMI function Set Segment Limit */
        movw    %ss,%bx                 /* Selector */
        int     $0x31                   /* Do service */

        xor     %ecx,%ecx               /* Clean up */
        xor     %edx,%edx               /* Clean up */

ok_stack:
        ret                             /* What we have is already bigger */

badstack:
        movl    $0x4c01,%eax
        int     $0x21
        jmp     badstack

        .data
        .globl  __stklen
        .comm   __stklen,4

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.