svp@csgrad.cs.vt.edu (Joel Patterson) (12/20/90)
I am trying to write context-switching code for a Symmetry under DYNIX. I need to have a frame pointer register for use with the stack (similar to the frame pointer register in a 68000). I think I should be able to use the BP register, but I am not sure. Can anyone help me on this? The Symmetry uses an 80386. Thanks, Joel -- Joel Patterson UUCP: svp@csgrad.UUCP 804-421-9398 INET: svp@csgrad.cs.vt.edu
rbj@uunet.UU.NET (Root Boy Jim) (12/20/90)
In article <776@creatures.cs.vt.edu> svp@csgrad.cs.vt.edu (Joel Patterson) writes:
? I am trying to write context-switching code for a Symmetry under DYNIX.
? I need to have a frame pointer register for use with the stack (similar
? to the frame pointer register in a 68000). I think I should be able to
? use the BP register, but I am not sure. Can anyone help me on this? The
? Symmetry uses an 80386.
? Joel Patterson UUCP: svp@csgrad.UUCP
? 804-421-9398 INET: svp@csgrad.cs.vt.edu
That's what Sequent does. I think that's the most common choice.
A cc -S command will tell you all you need to know.
--
Root Boy Jim Cottrell <rbj@uunet.uu.net>
Close the gap of the dark year in between
bakken@cs.arizona.edu (Dave Bakken) (12/22/90)
In article <776@creatures.cs.vt.edu> svp@csgrad.cs.vt.edu (Joel Patterson) writes: >I am trying to write context-switching code for a Symmetry under DYNIX. >I need to have a frame pointer register for use with the stack (similar >to the frame pointer register in a 68000). I think I should be able to >use the BP register, but I am not sure. Can anyone help me on this? The >Symmetry uses an 80386. > >Thanks, > Joel I don't rightly remember what the scoop is on that. But I had to write a context switching package for the '386 for our Sequent to port our distributed programming language, Synchronizing Resources (SR), to it. I remember that the Sequent docs were pretty skimpy on the calling convention details that I needed, so I used my friend "cc -S" a lot. But following are the '386-specific routines that I came up with. They have been tested with real users for almost a year, so they are stable. The top of the ``stack area'' is used for a register save area, and then the stack grows from the bottom of the stack area. A magic cookie is put on the stack and it servers as a sanity check we call often (if the cookie isn't there you've used too much stack and overwritten it. This is not guaranteed to work always but often does and is cheap.). To use the below functions, you call sr_build_context(code_ptr, stack, ...) and then sr_chg_context(stack). Note that sr_chg_context is called voluntarily by the generated code (the SR compiler spits out C...) so it only saves registers that are assumed to survive across function calls. Thus, it would probably be inappropriate for an interrupt/signal-driven context switch. Enjoy, Dave Bakken bakken@cs.arizona.edu P.S. SR is available via anonymous ftp from cs.arizona.edu for free and via tar tape for a modest charge. Send me email if you'd like more information about it (it runs on Suns, VAXen, Encore, and a bunch others besides Sequent). ======== snip ========== snip, snip =========== snippety-snip ====== /* i386.s - intel 80386 context switching code for Sequent Symmetry * * (This should work also for other Intel 80386 machines if they use the same * calling sequences and register conventions.) * * A context array is laid out like this: * * saved registers (%ebp, %ebx, %esi, %edi) * magic word for checking integrity * unused stack space * saved %esp <--- saved ebp points here * saved pc (return address) * error routine addr (if code returns, which is an error, it will go here) * arguments from sr_build_context call * * Registers %ebp, %ebx, %esi, and %edi are saved at the base of the array. * %eax, %ecx, and %edx aren't saved because C doesn't expect them to survive * over function calls. %esp is saved on the stack at subroutine entry. */ #define MAGIC 79797979 /* any unlikely long integer */ #define RSIZE 16 /* size of register save area */ .data .align 2 dummy_stack: /* fake initial context */ .long 0 /* 00 offset - %ebp */ .long 0 /* 04 offset - %ebx */ .long 0 /* 08 offset - %esi*/ .long 0 /* 12 offset - %edi */ .long MAGIC /* 16 offset - magic word for sanity check */ curr_stack: /* saves addr of current context (stack) */ .long dummy_stack .text .align 2 /* sr_build_context(code,buf,bufsize,a1,a2,a3,a4) -- create a new context. * * code entry point of the code to be executed in the context * buf buffer for holding the context array * bufsize size of the buffer * a1 - a4 four int-sized arguments to be passed to the code */ .globl _sr_build_context _sr_build_context: pushl %ebp /* save caller's frame pointer */ movl %esp,%ebp /* save caller's stack pointer */ movl 12(%ebp), %eax /* %eax = pointer to context array */ movl %eax, %esp addl 16(%ebp), %esp /* point stack to end of context array */ pushl 32(%ebp) /* push arg4 */ pushl 28(%ebp) /* push arg3 */ pushl 24(%ebp) /* push arg2 */ pushl 20(%ebp) /* push arg1 */ pushl $under /* push error addr in case context returns */ pushl 8(%ebp) /* push address for startind execution */ pushl $0 /* push dummy frame pointer */ movl %esp, (%eax) /* set initial frame pointer*/ movl $MAGIC, RSIZE(%eax) /* store magic word for integrity check */ leave /* restore stack and frame pointers */ ret /* return */ /* sr_chg_context(newstack) -- switch context to the specified stack */ .globl _sr_chg_context _sr_chg_context: pushl %ebp /* save old frame pointer */ movl %esp,%ebp /* save old stack pointer in frame pointer */ movl curr_stack,%eax /* load address of current context stack */ movl %ebp, 0(%eax) /* save registers in user context block */ movl %ebx, 4(%eax) movl %esi, 8(%eax) movl %edi, 12(%eax) addl $RSIZE,%eax cmpl %eax,%esp /* check that stack isn't overflowing */ jle over cmpl $MAGIC,(%eax) /* catch earlier overflow (maybe) */ jne over movl 8(%ebp), %eax /* load address of new context */ cmpl $MAGIC, RSIZE(%eax) /* make sure new stack looks okay */ jne bad movl %eax, curr_stack /* save address of new context */ movl 0(%eax), %ebp /* load registers for new context */ movl 4(%eax), %ebx movl 8(%eax), %esi movl 12(%eax), %edi leave /* restore %esp and %ebp */ ret /* return into new context */ /* sr_check_stk() -- check that the stack is not overflowing */ .globl _sr_check_stk _sr_check_stk: movl curr_stack, %eax addl $RSIZE, %eax cmpl %eax, %esp jle over ret /* stack problem handlers (these calls do not return) */ over: call _sr_stk_overflow under: call _sr_stk_underflow bad: call _sr_stk_corrupted ======== snip ========== snip, snip =========== snippety-snip ====== -- Dave Bakken, bakken@cs.arizona.edu, uunet!arizona!bakken, +1 602 621 4976 ``I am Iraq, I am an island. And Iraq feels no pain. And an island never cries.'' Paul Simon (sort of)