home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / libsrc / c / sys / setstack.s < prev    next >
Encoding:
Text File  |  1993-05-31  |  2.2 KB  |  70 lines

  1. /*  This routine potentially increases the stack size at runtime based on
  2.     the _stklen variable.  Only used by DPMI code.
  3.     Copyright (c) 1993  C. Sandmann
  4.     Environment:  called by crt0.s (and gcrt0.s)
  5.                   EAX, EBX, EBP, EDI, ESI disposable (cleared on return) */
  6.  
  7.     .text
  8.     .globl    __setstack
  9. __setstack:
  10.     movl    %esp,%eax
  11.     andl    $0xc0000000,%eax    /* clear all except upper bits */
  12.     jne    ok_stack        /* obviously not DPMI! */
  13.     movw    %ss,%ax
  14.     lsll    %eax,%ebx        /* stack segment limit */
  15.     movl    %esp,%eax        /* current location */
  16.     subl    %ebx,%eax        /* Free stack */
  17.     cmpl    %eax,__stklen
  18.     jb    ok_stack
  19.  
  20. /* Not enough stack.  Call sbrk() to get a new area.  Copy current ESP + 20
  21.    to end of new area (3 args + our stack).  Change ESP to new area.  Set new
  22.    limit to start of new area using DPMI services.  */
  23.  
  24.     pushl    __stklen
  25.     call    _sbrk            /* eax = got memory base */
  26.     popl    %ebx            /* remove _stklen */
  27.     cmpl    $0xffffffff,%eax    /* if eax = -1 failure */
  28.     je    badstack
  29.     addl    %eax,%ebx        /* ebx now is end of new stack area */
  30.     andl    $0xfffffff0,%ebx    /* 16 byte alignment */
  31.     addl    $0xfff,%eax        /* make stack base page aligned */
  32.     andl    $0xfffff000,%eax    /* 4096 byte alignment */
  33.  
  34. /* Now copy old stack to new stack.  We only need our part + 4 words, 3 for
  35.    the parameters to pass to main, one for our return EIP (4 extra safety) */
  36.     movl    %esp, %esi        /* Source is current stack */
  37.     subl    $0x20, %ebx        /* 8 longwords */
  38.     movl    %ebx, %edi        /* Destination is new stack */
  39.     movl    $8,%ecx
  40.     rep
  41.     movsl
  42.  
  43. /* New stack in place.  Change ESP to point to it.  Assumes new stack is
  44.    higher in memory so we don't get caught by limit.  Change limit using 
  45.    DPMI services. */
  46.  
  47.     movl    %ebx,%esp        /* Switch to new stack */
  48.     subl    $1,%eax            /* Low 12 bits all 1s */
  49.     pushl    %eax            /* Easiest way to move long to words */
  50.     popw    %dx
  51.     popw    %cx
  52.     movl    $8,%eax            /* DPMI function Set Segment Limit */
  53.     movw    %ss,%bx            /* Selector */
  54.     int    $0x31            /* Do service */
  55.  
  56.     xor    %ecx,%ecx        /* Clean up */
  57.     xor    %edx,%edx        /* Clean up */
  58.  
  59. ok_stack:
  60.     ret                /* What we have is already bigger */
  61.  
  62. badstack:
  63.     movl    $0x4c01,%eax
  64.     int    $0x21
  65.     jmp    badstack
  66.  
  67.     .data
  68.     .globl    __stklen
  69.     .comm    __stklen,4
  70.