免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4498 | 回复: 14

[进程管理] switch_to源码疑问 [复制链接]

论坛徽章:
0
发表于 2012-05-30 09:45 |显示全部楼层
本帖最后由 blake326 于 2012-06-04 11:06 编辑

switch的源码是这个:
它定义了ebx, ecx, edx, esi, edi几个局部变量(prev的内核栈上),然后output把这些变量写到相应的寄存器上了。这时什么意思?
但是具体这个内联汇编的流程看得不懂我。

这些局部变量存的什么值,每见到哪里用到了?

应该switch_to会保存ebx,ecx等到内核栈上,为什么这里好像颠倒了,把堆栈上的局部变量往寄存器写呢?




    #define switch_to(prev, next, last)                                        \
do {                                                                        \
        /*                                                                \
         * Context-switching clobbers all registers, so we clobber        \
         * them explicitly, via unused output variables.                \
         * (EAX and EBP is not listed because EBP is saved/restored        \
         * explicitly for wchan access and EAX is the return value of        \
         * __switch_to())                                                \
         */                                                                \
        unsigned long ebx, ecx, edx, esi, edi;                                \
                                                                        \
        asm volatile("pushfl\n\t"                /* save    flags */        \
                     "pushl %%ebp\n\t"                /* save    EBP   */        \
                     "movl %%esp,%[prev_sp]\n\t"        /* save    ESP   */ \
                     "movl %[next_sp],%%esp\n\t"        /* restore ESP   */ \
                     "movl $1f,%[prev_ip]\n\t"        /* save    EIP   */        \
                     "pushl %[next_ip]\n\t"        /* restore EIP   */        \
                     __switch_canary                                        \
                     "jmp __switch_to\n"        /* regparm call  */        \
                     "1:\t"                                                \
                     "popl %%ebp\n\t"                /* restore EBP   */        \
                     "popfl\n"                        /* restore flags */        \
                                                                        \
                     /* output parameters */                                \
                     : [prev_sp] "=m" (prev->thread.sp),                \
                       [prev_ip] "=m" (prev->thread.ip),                \
                       "=a" (last),                                        \
                                                                        \
                       /* clobbered output registers: */                \
                       "=b" (ebx), "=c" (ecx), "=d" (edx),                \
                       "=S" (esi), "=D" (edi)                                \
                                                                               \
                       __switch_canary_oparam                                \
                                                                        \
                       /* input parameters: */                                \
                     : [next_sp]  "m" (next->thread.sp),                \
                       [next_ip]  "m" (next->thread.ip),                \
                                                                               \
                       /* regparm parameters for __switch_to(): */        \
                       [prev]     "a" (prev),                                \
                       [next]     "d" (next)                                \
                                                                        \
                       __switch_canary_iparam                                \
                                                                        \
                     : /* reloaded segment registers */                        \
                        "memory");                                        \
} while (0)


另外我objdump -S sched.o 的结果, 没有看到相关ebx, ecx, edx, esi, edi的过程:
45658 #ifndef __ARCH_WANT_UNLOCKED_CTXSW
45659     spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
45660  8d2:   8d 43 10                lea    0x10(%ebx),%eax
45661  8d5:   b9 d2 08 00 00          mov    $0x8d2,%ecx
45662  8da:   ba 01 00 00 00          mov    $0x1,%edx
45663  8df:   e8 fc ff ff ff          call   8e0 <schedule+0x624>
45664 #endif
45665
45666     /* Here we just switch the register state and the stack. */
45667     switch_to(prev, next, prev);
45668  8e4:   8b 45 a8                mov    -0x58(%ebp),%eax
45669  8e7:   89 fa                   mov    %edi,%edx
45670  8e9:   9c                      pushf
45671  8ea:   55                      push   %ebp
45672  8eb:   89 a0 08 03 00 00       mov    %esp,0x308(%eax)
45673  8f1:   8b a7 08 03 00 00       mov    0x308(%edi),%esp
45674  8f7:   c7 80 10 03 00 00 0c    movl   $0x90c,0x310(%eax)
45675  8fe:   09 00 00
45676  901:   ff b7 10 03 00 00       pushl  0x310(%edi)
45677  907:   e9 fc ff ff ff          jmp    908 <schedule+0x64c>
45678  90c:   5d                      pop    %ebp
45679  90d:   9d                      popf
45680  90e:   89 45 a0                mov    %eax,-0x60(%ebp)
45681     /*
45682      * this_rq must be evaluated again because prev may have moved
45683      * CPUs since it called schedule(), thus the 'rq' on its stack
45684      * frame will be invalid.
45685      */
45686     finish_task_switch(this_rq(), prev);

论坛徽章:
0
发表于 2012-06-04 11:07 |显示全部楼层
顶~
顶顶~
顶顶顶~

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2012-06-04 11:20 |显示全部楼层
回复 1# blake326
我看了下我这边的编译文件,貌似也没有,纳闷了,难道gcc的特性修改了??

   

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2012-06-04 13:30 |显示全部楼层
回复 1# blake326
从嵌入汇编上看,好像是要把切换回来后的把那几个寄存器的值写入到相应的局部变量里。不过在反汇编代码里好像没找到相应的语句。作者是不是想看切换回来后ebx, ecx, edx, esi, edi的值啊。

   

论坛徽章:
0
发表于 2012-06-04 14:08 |显示全部楼层
回复 4# firkraag


                     /* clobbered output registers: */                \
                       "=b" (ebx), "=c" (ecx), "=d" (edx),                \
                       "=S" (esi), "=D" (edi)                                \


这是输出,把ebx变量输出到ebx寄存器。ecx变量输出到ecx寄存器。。。。。
你是不是搞反了。

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2012-06-04 14:22 |显示全部楼层
回复 5# blake326
你说的那是输入寄存器,lz搞反了。

http://hi.baidu.com/yjfei66/blog ... 63182eafc3aba4.html

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
发表于 2012-06-04 14:22 |显示全部楼层
回复 5# blake326

你反了。

论坛徽章:
0
发表于 2012-06-04 14:28 |显示全部楼层
   /* clobbered output registers: */                \
                       "=b" (ebx), "=c" (ecx), "=d" (edx),                \
                       "=S" (esi), "=D" (edi)                                \

输出:
=b,表示该内联汇编会修改ebx寄存器,内容从哪里来,就是括号的ebx变量?

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2012-06-04 14:37 |显示全部楼层
回复 8# blake326
输出说的是这段嵌入汇编的输出。这的意思就是将嵌入汇编结束时ebx寄存器的值写入ebx变量。

   

论坛徽章:
0
发表于 2012-06-05 09:46 |显示全部楼层
还是不知道switch_to到底要不要保存这些ebx, ecx, edx, esi, edi寄存器?
如果要保存,怎样保存的?


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP