注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

FY

Johnson 's Blog

 
 
 

日志

 
 

linux 2.4.0 switch_to问题  

2017-01-03 09:23:50|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

#define switch_to(prev,next,last) do {                               \

       asm volatile(//以下3条指令是由输入寄存器而隐含的,在一开始就要执行的

                       movl prev à %%eax

                       movl next à %%edx

                       movl prev à %%ebx

            "pushl %%esi\n\t"                               \

                   "pushl %%edi\n\t"                               \

                   "pushl %%ebp\n\t"                              \

                   "movl %%esp,%0\n\t"    /* save ESP */            \

                   "movl %3,%%esp\n\t" /* restore ESP */      \

                   "movl $1f,%1\n\t"          /* save EIP */             \

                   "pushl %4\n\t"         /* restore EIP */ \

                   "jmp __switch_to\n"                           \

                   "1:\t"                                     \

                   "popl %%ebp\n\t"                               \

                   "popl %%edi\n\t"                                \

                   "popl %%esi\n\t"                                 \

                       movl %%ebx à last指定的变量中 //输出寄存器隐含的一条指令

:"=m" (prev->thread.esp),"=m" (prev->thread.eip),       \

                    "=b" (last)                                   \

                   :"m" (next->thread.esp),"m" (next->thread.eip),    \

                    "a" (prev), "d" (next),                        \

                    "b" (prev));                                 \

} while (0)

 

由于定义了输入寄存器,所以一开始要先将各变量的内容先存到各输入寄存器中

接着执行到"movl %3,%%esp\n\t"     /* restore ESP */      \

进程A切换到进程B,即内核栈从A变成B后,任务和栈或栈上变更有关的操作都将是在进程B的栈中进行了。

又由于定义了输出寄存器,所以整个嵌入汇编最后还会有一条指令,是将EBX寄存器的内容赋值给LAST变量,这是由定义了输出寄存器而隐含的。

 

EBX寄存器首先它先是作为输入寄存器,所以它一开始存入的是PREV的内容,注意这里的PREV是进程A的内核栈上的内容,因为输入寄存器的那3条指令是一开始就执行了,当时还没切换栈,还是进程A的内核栈,也就是PREV的内容是指向进程Acurrent.而在整个switch_to的过程中,并没有修改EBX的操作。所以switch_to的最后,还有将EBX寄存器输出赋值给LAST变量,而由于内核栈已经切换到B,这里的LAST变量虽然也是栈上的局部变量,但已经是进程B栈上的了,也就是进程Bschedule函数中的局部变量PREV了。

所以切换到B后,对B来讲,它从switch_to返回了,它的PREV局部变量中已经是存放着的是指向上一个被切过来的进程Atask_struct了。接着调用schedule_tail,传入RREV,将进程Ahas_cpu0,让进程A将来可以再次被调度。否则进程Ahas_cpu=1,就无法通过can_schedule的判定,从而不能被调度了。

  评论这张
 
阅读(2)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017