2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
6 /*****************************************************************************
10 AROS_LH1(void, StackSwap,
13 AROS_LHA(struct StackSwapStruct *, newStack, A0),
16 struct ExecBase *, SysBase, 122, Exec)
19 This function switches to the new stack given by the parameters in the
20 stackswapstruct structure. The old stack parameters are returned in
21 the same structure so that the stack can be restored later
24 newStack - parameters for the new stack
40 ******************************************************************************/
41 #include "aros/i386/asm.h"
42 #include <aros/config.h>
45 .globl AROS_SLIB_ENTRY(StackSwap,Exec,122)
46 _FUNCTION(AROS_SLIB_ENTRY(StackSwap,Exec,122))
47 AROS_SLIB_ENTRY(StackSwap,Exec,122):
48 /* Save %ebx content */
51 /* Take the function's parameters; SysBase is in %eax */
52 movl 8(%esp), %ebx //newStack
54 /* Disable interrupts, to be sure they always find a good stackframe */
57 /* FindTask(NULL) in %edx */
58 movl ThisTask(%eax), %edx
60 /* Swap Lower boundaries, %ecx is used as temp register */
61 movl tc_SPLower(%edx), %ecx
62 xchgl %ecx, stk_Lower(%ebx)
63 movl %ecx, tc_SPLower(%edx)
65 /* Swap Upper boundaries, %ecx is used as temp register */
66 movl tc_SPUpper(%edx), %ecx
67 xchgl %ecx, stk_Upper(%ebx)
68 movl %ecx, tc_SPUpper(%edx)
70 movb tc_Flags(%edx), %cx
71 test $TF_STACKCHK, %cx
74 /* Fill [stk_Lower .. stk_Pointer - 16] with 0xE1 */
79 /* Destination register = %edi = NEW SPLower.
80 Which was already swapped above, so to be found
81 in task->tc_SPLower */
82 movl tc_SPLower(%edx), %edi
84 /* %ecx = count register = NEW SP register - NEW SP_Lower - 16 */
85 movl stk_Pointer(%ebx), %ecx
89 /* byte value to store */
92 /* direction to store: forward */
95 /* do the store operation: put %ecx times %al into memory starting at %edi. */
103 /* Now restore %ebx */
106 /* Pop function's return address and arguments before we swap stacks.
107 This is needed for proper stack balancing (saved value of sp must be
108 caller's stack pointer, right before StackSwap() was called. This way
109 second StackSwap() call will restore the stack to exactly the same state. */
110 popl %ecx // return address
111 popl %edx // newStack
113 /* Swap stack pointers */
114 xchgl %esp, stk_Pointer(%edx)
116 /* Reenable interrupts. */
120 * Now we should make the top of new stack to look exactly like the
121 * old one. This means it should contain arguments passed to StackSwap(),
122 * because the caller now will want to clear the stack and remove arguments.
123 * Arguments were: newStack. So we need to push it to the new stack.
127 /* Return. %ecx contains the return address, and the stack is already
128 adjusted, we don't need, or even can, use ret here. */