.globl task_switch // This function takes a pointer // to a PROC structure and jump // to this process task_switch: pop %esi // Switch to the new task kernel stack mov 72(%esi), %ss mov 76(%esi), %esp // If we where in kernel mode we should keep using the same // stack which is stored in regs.ss and regs.esp by schedule mov 24(%esi), %eax cmp $0x08, %eax # Check if we were in kernel mode jne skip_kernel_stack mov 32(%esi), %ss mov 36(%esi), %esp skip_kernel_stack: // Setup process page directory to be able to use task stack mov 4(%esi), %eax mov %eax, %cr3 push 8(%esi) # eax (cf PROC struct) push 12(%esi) # ebx push 16(%esi) # ecx push 20(%esi) # edx push 40(%esi) # ebp push 48(%esi) # edi push 52(%esi) # ds push 56(%esi) # es push 60(%esi) # fs push 64(%esi) # gs // Don't forget to clear the interrupt movb $0x20, %al outb %al, $0x20 // Setup registers pop %gs pop %fs pop %es pop %ds pop %edi pop %ebp pop %edx pop %ecx pop %ebx pop %eax // Perform the task switch push %eax mov 24(%esi), %eax cmp $0x08, %eax # Check if we were in kernel mode pop %eax je skip_stack push 32(%esi) # ss push 36(%esi) # esp skip_stack: push 68(%esi) # eflags push 24(%esi) # cs push 28(%esi) # eip mov 52(%esi), %ds # Choose the right data segment mov 44(%esi), %esi # Now restore task esi iret # Launch task