home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / config / i386 / stackswap.s < prev    next >
Encoding:
Text File  |  1997-02-07  |  2.7 KB  |  122 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: stackswap.s,v 1.11 1997/02/06 15:19:52 ldp Exp $
  4.  
  5.     Desc: Change the stack of a task.
  6.     Lang: english
  7. */
  8.  
  9. /******************************************************************************
  10.  
  11.     NAME
  12.     AROS_LH1(void, StackSwap,
  13.  
  14.     SYNOPSIS
  15.     AROS_LHA(struct StackSwapStruct *, sss, A0),
  16.  
  17.     LOCATION
  18.     struct ExecBase *, SysBase, 122, Exec)
  19.  
  20.     FUNCTION
  21.     Change the stack of a task.
  22.  
  23.     INPUTS
  24.     sss - The description of the new stack
  25.  
  26.     RESULT
  27.     There will be a new stack.
  28.  
  29.     NOTES
  30.     Calling this routine the first time will change sss and
  31.     calling it a second time, the changes will be undone.
  32.  
  33.     EXAMPLE
  34.  
  35.     BUGS
  36.  
  37.     SEE ALSO
  38.  
  39.     INTERNALS
  40.     This is a symmetrical routine. If you call it twice, then
  41.     everything will be as it was before.
  42.  
  43.     HISTORY
  44.  
  45. ******************************************************************************/
  46.  
  47.     #include "machine.i"
  48.  
  49.     .text
  50.     .balign 16
  51.     .globl    AROS_SLIB_ENTRY(StackSwap,Exec)
  52.     .type    AROS_SLIB_ENTRY(StackSwap,Exec),@function
  53.  
  54.     /* The stack looks like this:
  55.  
  56.         8 SysBase
  57.         4 sss
  58.         0 return address
  59.     */
  60.  
  61. #define sss        4
  62. #define SysBase     8
  63.  
  64. AROS_SLIB_ENTRY(StackSwap,Exec):
  65.     /* Read parameter sss */
  66.     movl sss(%esp),%edx
  67.  
  68.     /* copy new SP into ecx */
  69.     movl stk_Pointer(%edx),%ecx
  70.  
  71.     /* Pop return address and sss from the current stack and copy them
  72.         onto the one specified in sss */
  73.     popl %eax            /* pop Return address */
  74.     movl %eax,-12(%ecx)         /* Push return address on new stack */
  75.     popl %eax            /* pop sss */
  76.     movl %eax,-8(%ecx)          /* Push sss on new stack */
  77.  
  78.     /* Copy SysBase from the current stack onto the one in sss */
  79.     movl (%esp),%eax
  80.     movl %eax,-4(%ecx)          /* Push SysBase on new stack */
  81.  
  82.     /* Calc new start of stack in sss */
  83.     addl $-12,%ecx
  84.  
  85.     /* Call Disable() (SysBase is still on the stack) */
  86.     leal Disable(%eax),%eax
  87.     call *%eax
  88.     popl %eax            /* Remove SysBase from current stack */
  89.  
  90.     movl %esp,stk_Pointer(%edx) /* Save current SP in sss */
  91.     movl %ecx,%esp            /* Load the new stack */
  92.  
  93.     movl ThisTask(%eax),%ecx
  94.     leal tc_SPLower(%ecx),%ecx  /* ecx = &SysBase->ThisTask->tc_SPLower */
  95.  
  96.     push %ebx            /* Save register */
  97.  
  98.     /* Swap ThisTask->tc_SPLower and sss->stk_Lower */
  99.     movl stk_Lower(%edx),%eax
  100.     movl (%ecx),%ebx
  101.     movl %eax,(%ecx)
  102.     movl %ebx,stk_Lower(%edx)
  103.  
  104.     /* Swap tc_SPUpper and sss->stk_Upper, too */
  105.     movl stk_Upper(%edx),%eax
  106.     movl 4(%ecx),%ebx
  107.     movl %eax,4(%ecx)
  108.     movl %ebx,stk_Upper(%edx)
  109.  
  110.     popl %ebx            /* Restore register */
  111.  
  112.     /* Call Enable() */
  113.     movl SysBase(%esp),%eax
  114.     pushl %eax            /* push SysBase on new stack */
  115.     leal Enable(%eax),%eax      /* call enable */
  116.     call *%eax
  117.     addl $4,%esp            /* Clean stack */
  118.  
  119.     /* Note that at this time, the new stack from sss contains the
  120.        same values as the previous stack */
  121.     ret
  122.