完毕一个简单的时间片轮转多道程序内核代码(二)

完毕一个简单的时间片轮转多道程序内核代码

重要汇编代码分析

    asm volatile(
        "movl %1,%%esp
	"
        "pushl %1
	" 
        "pushl %0
	" 
        "ret
	" 
        "popl %%ebp
	"
        : 
        : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp) 
    );

image

image

image

image

image

image

  • 保存恢复进程上下文

    asm volatile(   
        "pushl %%ebp
    	"   //保存当前 ebp
        "movl %%esp,%0
    	"     //保存 esp
        "movl %2,%%esp
    	"     //加载下一个进程的 esp
        "movl $1f,%1
    	"          //保存 eip
        "pushl %3
    	"      //
        "ret
    	"       //加载 eip
        "1:	"      //下一个进程開始运行
        "popl %%ebp
    	"    //
        : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
        : "m" (next->thread.sp),"m" (next->thread.ip)
    ); 
    
    
    //假设没有正在运行的进程
    asm volatile(   
        "pushl %%ebp
    	"      //保存 ebp
        "movl %%esp,%0
    	"    //保存 esp
        "movl %2,%%esp
    	"    //加载 esp
        "movl %2,%%ebp
    	"    //加载 ebp
        "movl $1f,%1
    	"      //保存 eip  
        "pushl %3
    	" 
        "ret
    	"              //加载上下文
        : "=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号)開始运行
  • 再次发生中断,须要切换进程……
  • ……
原文地址:https://www.cnblogs.com/mfrbuaa/p/5235028.html