Combined set_registers and get_registers into swap_registers.

This commit is contained in:
Eric Holk 2011-06-23 20:23:04 -07:00
parent 98dee91f25
commit 860e8fd98b
2 changed files with 20 additions and 57 deletions

View file

@ -13,15 +13,17 @@ Saves a set of registers. This is used by our implementation of
getcontext.
The registers_t variable is in (%esp)
*/
.globl get_registers
get_registers:
movl 4(%esp), %eax
movl %eax, 0(%eax)
*/
// swap_registers(registers_t *oregs, registers_t *regs)
.globl swap_registers
swap_registers:
// save the old context
movl 4(%esp), %eax
//movl %eax, 0(%eax)
movl %ebx, 4(%eax)
movl %ecx, 8(%eax)
movl %edx, 12(%eax)
//movl %ecx, 8(%eax)
//movl %edx, 12(%eax)
movl %ebp, 16(%eax)
movl %esi, 20(%eax)
movl %edi, 24(%eax)
@ -43,17 +45,12 @@ get_registers:
movl %esp, 28(%eax)
movl %ecx, 48(%eax)
// return 0
xor %eax, %eax
jmp *%ecx
.globl set_registers
set_registers:
movl 4(%esp), %eax
// restore the new context
movl 4(%esp), %eax
movl 4(%eax), %ebx
// save ecx for later...
movl 12(%eax), %edx
//movl 12(%eax), %edx
movl 16(%eax), %ebp
movl 20(%eax), %esi
movl 24(%eax), %edi
@ -71,36 +68,5 @@ set_registers:
push %ecx
popf
// get ready to return.
mov 48(%eax), %ecx
push %ecx
// okay, now we can restore ecx.
movl 8(%eax), %ecx
// return 1 to the saved eip
movl $1, %eax
ret
// swap_registers(registers_t *oregs, registers_t *regs)
.globl swap_registers
swap_registers:
// %eax = get_registers(oregs);
movl 4(%esp), %eax
push %eax
call get_registers
// if(!%eax) goto call_set
test %eax, %eax
jz call_set
// else
addl $4, %esp
ret
call_set:
// set_registers(regs)
movl 12(%esp), %eax
movl %eax, 0(%esp)
call set_registers
// set_registers never returns
// Return!
jmp *48(%eax)

View file

@ -5,17 +5,12 @@
#include <stdio.h>
#include <stdlib.h>
//extern "C" uint32_t CDECL get_registers(registers_t *regs)
// asm ("get_registers");
extern "C" uint32_t CDECL swap_registers(registers_t *oregs,
registers_t *regs)
asm ("swap_registers");
context::context()
: next(NULL)
{
//get_registers(&regs);
swap_registers(&regs, &regs);
}
void context::swap(context &out)
@ -24,13 +19,15 @@ void context::swap(context &out)
}
void context::call(void *f, void *arg, void *stack) {
// Get the current context, which we will then modify to call the
// given function.
swap(*this);
// set up the trampoline frame
uint32_t *sp = (uint32_t *)stack;
// Shift the stack pointer so the alignment works out right.
sp = align_down(sp) - 2;
*--sp = (uint32_t)this;
sp = align_down(sp) - 3;
*--sp = (uint32_t)arg;
*--sp = 0xdeadbeef;