nuclear@54: .text nuclear@57: /* switch_stack(uint32_t new_stack, uint32_t *old_stack_ptr) nuclear@57: * switches to the new stack and returns the old stack pointer, which is nuclear@57: * also copied to the address passed as the second argument. nuclear@54: */ nuclear@54: .globl switch_stack nuclear@54: switch_stack: nuclear@57: movl %esp, %eax /* old stack in eax */ nuclear@57: movl 8(%esp), %edx nuclear@57: cmpl $0, %edx /* if old_stack_ptr is null, skip ahead */ nuclear@57: jz oldp_is_null nuclear@57: movl %eax, (%edx) /* otherwise *old_stack_ptr = eax */ nuclear@57: oldp_is_null: nuclear@57: movl 4(%esp), %esp /* set the new stack */ nuclear@54: ret nuclear@57: nuclear@57: /* get_instr_stack_ptr(uint32_t *eip, uint32_t *esp) nuclear@57: * returns the current instruction and stack pointers at the same nuclear@57: * point in execution, so that a newly-forked process with these nuclear@57: * values will just return from this function and continue on. nuclear@57: */ nuclear@57: .globl get_instr_stack_ptr nuclear@57: get_instr_stack_ptr: nuclear@57: call get_instr_ptr nuclear@57: movl %eax, 4(%esp) nuclear@57: movl %esp, 8(%esp) nuclear@57: ret nuclear@57: nuclear@57: /* get_instr_ptr(void) nuclear@57: * returns the address of the next instruction after the call to this function nuclear@57: */ nuclear@57: .globl get_instr_ptr nuclear@57: get_instr_ptr: nuclear@57: movl (%esp), %eax nuclear@57: ret nuclear@57: nuclear@57: /* get_caller_instr_ptr(void) nuclear@57: * returns the address of the next instruction after the call to the function that nuclear@57: * called this function. nuclear@57: * NOTE: will only work properly when called from a function that uses ebp to point nuclear@57: * to its stack frame, which means all of the C functions but pretty much none of nuclear@57: * our assembly functions. nuclear@57: */ nuclear@57: .globl get_caller_instr_ptr nuclear@57: get_caller_instr_ptr: nuclear@57: movl 4(%ebp), %eax nuclear@57: ret nuclear@57: nuclear@58: /* this is where we end up when we first context_switch to a newly forked nuclear@58: * process. The interrupt frame is already there, so we just call intr_ret nuclear@58: * to return to user space nuclear@58: */ nuclear@57: .globl just_forked nuclear@57: just_forked: nuclear@57: call intr_ret