about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/setcontext.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/setcontext.S')
-rw-r--r--sysdeps/unix/sysv/linux/i386/setcontext.S53
1 files changed, 20 insertions, 33 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/setcontext.S b/sysdeps/unix/sysv/linux/i386/setcontext.S
index cbe9f08ce5..ebed2ce572 100644
--- a/sysdeps/unix/sysv/linux/i386/setcontext.S
+++ b/sysdeps/unix/sysv/linux/i386/setcontext.S
@@ -1,5 +1,5 @@
 /* Install given context.
-   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -53,39 +53,26 @@ ENTRY(__setcontext)
 	movl	oFS(%eax), %ecx
 	movw	%cx, %fs
 
+	/* Fetch the address to return to.  */
+	movl	oEIP(%eax), %ecx
+
 	/* Load the new stack pointer.  */
-	movl	oESP(%eax), %ecx
-	/* Make room for 8 registers and the return address.  We will load
-	   the values from the stack.  */
-	subl	$36, %ecx
-
-	/* Move the values of all the 32-bit registers (except ESP) on
-	   the stack.  This happens in the form the 'popa' instruction
-	   expects it.  Before this block put the address of the code
-	   to execute.  */
-	movl	oEDI(%eax), %ebx
-	movl	oESI(%eax), %edx
-	movl	oEBP(%eax), %esi
-	movl	oEBX(%eax), %edi
-	movl	%ebx, (%ecx)
-	movl	%edx, 4(%ecx)
-	movl	%esi, 8(%ecx)
-	movl	%edi, 16(%ecx)
-	movl	oEDX(%eax), %ebx
-	movl	oECX(%eax), %edx
-	movl	oEAX(%eax), %esi
-	movl	oEIP(%eax), %edi
-	movl	%ebx, 20(%ecx)
-	movl	%edx, 24(%ecx)
-	movl	%esi, 28(%ecx)
-	movl	%edi, 32(%ecx)
-
-	/* Set the new stack address.  The stack points now to the block
-	   we put the register content in.  */
-	movl	%ecx, %esp
-	/* Restore the register content.  */
-	popa
-	/* The following 'ret' will pop the addres of the code and jump
+	movl	oESP(%eax), %esp
+
+	/* Push the return address on the new stack so we can return there.  */
+	pushl	%ecx
+
+	/* Load the values of all the 32-bit registers (except ESP).
+	   Since we are loading from EAX, it must be last.  */
+	movl	oEDI(%eax), %edi
+	movl	oESI(%eax), %esi
+	movl	oEBP(%eax), %ebp
+	movl	oEBX(%eax), %ebx
+	movl	oEDX(%eax), %edx
+	movl	oECX(%eax), %ecx
+	movl	oEAX(%eax), %eax
+
+	/* The following 'ret' will pop the address of the code and jump
 	   to it.  */
 
 L(pseudo_end):