switch.S 1.2 KB

123456789101112131415161718192021222324252627
  1. [bits 32]
  2. section .text
  3. global switch_to ; void switch_to(struct task_struct *cur, struct task_struct *next);
  4. switch_to:
  5. ; 栈中此处是返回地址
  6. push esi
  7. push edi
  8. push ebx
  9. push ebp
  10. mov eax, [esp + 20] ; 得到栈中的参数 cur, cur = [esp + 20]
  11. mov [eax], esp ; 保存栈顶指针 esp 到task_struct 的 self_kstack 字段。
  12. ; self_kstack 在 task_struct 中的偏移为 0,所以直接往 thread 开头处存储 4 字节便可
  13. ;-------------------- 上面是备份当前线程环境,下面是恢复下一个线程环境 -------------------------------------
  14. mov eax, [esp + 24] ; 得到栈中的参数 next, next = [esp + 24]
  15. mov esp, [eax] ; pcb 的第一个成员是 self_kstack 成员
  16. ; 它用来记录 0 级栈顶指针,被换上 CPU 时用来恢复 0 级栈
  17. ; 因此,恢复 esp 到 pcb 的 self_kstack 位置,就可以恢复 0 级栈
  18. pop ebp
  19. pop ebx
  20. pop edi
  21. pop esi
  22. ret ; 返回到上面 switch_to 下面的注释返回地址
  23. ; 未由中断进入,第一次执行时会返回到 kernel_thread