- 该宏有三个参数:prev, next, last。它们都是局部变量。
prev:输入参数,变量值为旧进程描述符的地址。
next:输入参数,变量值为新进程描述符的地址。
last:输出参数,用来记录该进程是由哪个进程切换而来的,即保存 在当前进程之前 占用cpu的进程的 进程描述符地址。
- 为什么需要last这个局部变量呢?
因为:
首先,记录前一进程的进程描述符地址,对进程切换是很有用的,具体什么用途,以后再说。
其次,switch_to宏由就进程调用,在新进程结束,新进程如果想获取旧进程描述符地址,不能直接读取局部变量prev(因为prev存放在该宏调用者,即旧进程的内核栈中,新进程无法访问旧进程的内核栈),所以就需要一个输出参数将旧进程描述符地址传递给新进程(实现方法就是利用cpu寄存器%eax,在切换过程中该寄存器的值不变,也就是说,在旧进程中,将prev存入%eax,在新进程恢复执行后,将%eax的内容放入last)。
- 该宏的实现过程
1、将新旧进程描述符地址存放在cpu寄存器中
mov prev,%eax
mov next,%edx
2、保存旧进程部分上下文
pushl //eflags
push %ebp
3、进行栈切换
mov %esp,prev->thread_info.esp
mov (%edx)->thread_info.esp,%esp
4、指令地址切换,执行流由旧进程进入新进程
mov %eip或标签1的指令地址,prev->thread_info.eip
push (%edx)->thread_info.eip
跳入_switch_to()函数
6、将旧进程描述符地址放入last变量
mov %eax,last