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 pushl %eax /* Arg1: Sysbase */
59 pushl $0 /* Arg0: NULL */
61 movl %eax, %edx /* ThisTask to %edx */
62 movl 4(%esp), %eax /* Restore SysBase from stack */
63 addl $8, %esp /* Move stack pointer back */
64 /* movl ThisTask(%eax), %edx */
66 /* Swap Lower boundaries, %ecx is used as temp register */
67 movl tc_SPLower(%edx), %ecx
68 xchgl %ecx, stk_Lower(%ebx)
69 movl %ecx, tc_SPLower(%edx)
71 /* Swap Upper boundaries, %ecx is used as temp register */
72 movl tc_SPUpper(%edx), %ecx
73 xchgl %ecx, stk_Upper(%ebx)
74 movl %ecx, tc_SPUpper(%edx)
76 movb tc_Flags(%edx), %cx
77 test $TF_STACKCHK, %cx
80 /* Fill [stk_Lower .. stk_Pointer - 16] with 0xE1 */
85 /* Destination register = %edi = NEW SPLower.
86 Which was already swapped above, so to be found
87 in task->tc_SPLower */
88 movl tc_SPLower(%edx), %edi
90 /* %ecx = count register = NEW SP register - NEW SP_Lower - 16 */
91 movl stk_Pointer(%ebx), %ecx
95 /* byte value to store */
98 /* direction to store: forward */
101 /* do the store operation: put %ecx times %al into memory starting at %edi. */
109 /* Now restore %ebx */
112 /* Pop function's return address and arguments before we swap stacks.
113 This is needed for proper stack balancing (saved value of sp must be
114 caller's stack pointer, right before StackSwap() was called. This way
115 second StackSwap() call will restore the stack to exactly the same state. */
116 popl %ecx // return address
117 popl %edx // newStack
119 /* Swap stack pointers */
120 xchgl %esp, stk_Pointer(%edx)
122 /* Reenable interrupts. */
126 * Now we should make the top of new stack to look exactly like the
127 * old one. This means it should contain arguments passed to StackSwap(),
128 * because the caller now will want to clear the stack and remove arguments.
129 * Arguments were: newStack. So we need to push it to the new stack.
133 /* Return. %ecx contains the return address, and the stack is already
134 adjusted, we don't need, or even can, use ret here. */