+ .global switch_to
+ switch_to:
+ # 约定
+ # arg1: 目标进程PCB地址 (next
+
+ popl %ebx # next
+ movl __current, %eax
+ movl proc_page_table(%eax), %ecx # __current->pagetable
+ movl proc_page_table(%ebx), %eax # next->pagetable
+
+ cmpl %ecx, %eax # if(next->pagtable != __current->pagetable) {
+ jz 1f
+ movl %eax, %cr3 # cpu_lcr3(next->pagetable)
+ # }
+ 1:
+ movl %ebx, __current # __current = next
+
+ # 我们已经处在了新的地址空间,为了避免影响其先前的栈布局
+ # 需要使用一个临时的栈空间
+ movl $tmp_stack, %esp
+
+ # 更新 tss
+ movl proc_intr_ctx(%ebx), %eax # proc->intr_ctx
+ movl iesp(%eax), %eax # intr_ctx->esp
+ movl %eax, (tss_esp0_off + _tss)
+
+ call signal_dispatch # kernel/signal.c
+
+ test %eax, %eax # do we have signal to handle?
+ jz 1f
+ jmp handle_signal
+ 1:
+ movl proc_intr_ctx(%ebx), %eax
+ jmp soft_iret
+
+ .global handle_signal