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

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

重要汇编代码分析

    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) 
    );

image

image

image

image

image

image

  • 保存恢复进程上下文

    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号)開始运行
  • 再次发生中断,须要切换进程……
  • ……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值