完毕一个简单的时间片轮转多道程序内核代码(二)
完毕一个简单的时间片轮转多道程序内核代码
重要汇编代码分析
asm volatile(
"movl %1,%%esp\n\t"
"pushl %1\n\t"
"pushl %0\n\t"
"ret\n\t"
"popl %%ebp\n\t"
:
: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)
);






保存恢复进程上下文
asm volatile( "pushl %%ebp\n\t" //保存当前 ebp "movl %%esp,%0\n\t" //保存 esp "movl %2,%%esp\n\t" //加载下一个进程的 esp "movl $1f,%1\n\t" //保存 eip "pushl %3\n\t" // "ret\n\t" //加载 eip "1:\t" //下一个进程開始运行 "popl %%ebp\n\t" // : "=m" (prev->thread.sp),"=m" (prev->thread.ip) : "m" (next->thread.sp),"m" (next->thread.ip) ); //假设没有正在运行的进程 asm volatile( "pushl %%ebp\n\t" //保存 ebp "movl %%esp,%0\n\t" //保存 esp "movl %2,%%esp\n\t" //加载 esp "movl %2,%%ebp\n\t" //加载 ebp "movl $1f,%1\n\t" //保存 eip "pushl %3\n\t" "ret\n\t" //加载上下文 : "=m" (prev->thread.sp),"=m" (prev->thread.ip) : "m" (next->thread.sp),"m" (next->thread.ip) );
举例分析:假设有三个进程
- 从 mymain.c 中的__init my_start_kernel方法開始运行
- 新建 pid=0的进程。而且将其状态设置为0(runnable)。设置进程入口地址、栈地址
- 从0号进程复制1、2号进程,而且将0的 next 赋值为1号的入口地址,1号赋值为2号的入口地址
- 将0号进程赋值为当前正在运行进程(my_current_task = &task[0];)
- 运行汇编代码:保存进程信息,開始运行0号进程
- 发生中断。须要切换进程
- 运行汇编代码:保存当前进程的ebp、esp、eip(当前进程上下文)
- 加载下一个进程(1号)的上下文(esp、eip)
- 下一个进程(1号)開始运行
- 再次发生中断,须要切换进程……
- ……
浙公网安备 33010602011771号