免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3219 | 回复: 4
打印 上一主题 下一主题

为什么switch_to函数中没有对通用寄存器进行保存和切换? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-22 16:37 |只看该作者 |倒序浏览
为什么在进程切换函数switch_to和__switch_to中,我只看到了对SP,IP,FS,GS等少数寄存器的保存和切换,而没有对通用寄存器(EBX,ECX,EDX,ESI,EDI等)的保存和切换? 这些通用寄存器是何时保存和切换的?书上说这些通用寄存器已经在切换前保存到了内核态堆栈中,何时保存的?多谢!

论坛徽章:
0
2 [报告]
发表于 2010-12-23 15:03 |只看该作者
本帖最后由 bigrat023 于 2010-12-23 15:09 编辑

http://blog.csdn.net/yunsongice/archive/2010/04/22/5515965.aspx里面有一段:
"进程切换只发生在内核态。在执行切换之前,即通过中断的方式执行系统调用由用户态进入内核态时,linux从用户态转移到内核态有三个途径,系统调用,中断,异常,对应的代码在/arch/i386/kernel/entry.S中。用户进程使用的所有寄存器内容都已被SAVE_ALL汇编指令压入内核态堆栈"

看来不仅是内核在调用schedule()之前,而是在用户进程进入内核时,用户态的寄存器值就都保存在kernel stack里了。

至于内核态的寄存器值?我感觉是不需要保存的,因为switch_to里本来就不改变 ebx/edx等的值

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2010-12-24 12:39 |只看该作者
为什么在进程切换函数switch_to和__switch_to中,我只看到了对SP,IP,FS,GS等少数寄存器的保存和切换,而没有 ...
巨人史玉柱 发表于 2010-12-22 16:37



    cpu的基础问题。那些通用寄存器通常都是用来运算的,不保留进程的相关信息。那些信息变化那么频繁,干嘛要去保留那些信息?况且没有那些通用寄存器,swithc_to无法完成工作。

总之关于通用寄存器的信息不用管。和进程信息相关不大。

论坛徽章:
0
4 [报告]
发表于 2010-12-28 03:07 |只看该作者
回复 2# bigrat023


   

就是说进程切换都是发生在内核态,而通用寄存器中的信息已经在从用户态切入到内核态的时候保存到内核栈里面了。 可是从“刚进入内核态”到“执行switch_to”这一段时间内,进程一直在内核态运行,那么在这段时间内难道没有使用通用寄存器吗?难道不用保存吗?谢谢

论坛徽章:
0
5 [报告]
发表于 2010-12-28 11:30 |只看该作者
回复 4# 巨人史玉柱

这是x86_64架构上的switch_to宏:(linux-2.6.1

  1.    20 #define __EXTRA_CLOBBER  \
  2.    21     ,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"
  3.    22
  4.    23 /* Save restore flags to clear handle leaking NT */
  5.    24 #define switch_to(prev,next,last) \
  6.    25     asm volatile(SAVE_CONTEXT                           \
  7.    26              "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */   \
  8.    27              "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \
  9.    28              "call __switch_to\n\t"                   \
  10.    29              ".globl thread_return\n"                   \
  11.    30              "thread_return:\n\t"                       \
  12.    31              "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"           \
  13.    32              "movq %P[thread_info](%%rsi),%%r8\n\t"           \
  14.    33              LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"    \
  15.    34              "movq %%rax,%%rdi\n\t"                       \
  16.    35              "jc   ret_from_fork\n\t"                     \
  17.    36              RESTORE_CONTEXT                            \
  18.    37              : "=a" (last)                        \
  19.    38              : [next] "S" (next), [prev] "D" (prev),              \
  20.    39                [threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \
  21.    40                [ti_flags] "i" (offsetof(struct thread_info, flags)),\
  22.    41                [tif_fork] "i" (TIF_FORK),             \
  23.    42                [thread_info] "i" (offsetof(struct task_struct, thread_info)), \
  24.    43                [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))   \
  25.    44              : "memory", "cc" __EXTRA_CLOBBER)
复制代码
这个__EXTRA_CLOBBER 指的就是rcx,rdx等寄存器的值在展开成汇编时不能使用他们,这样也就确保了这些寄存器的值不被改变。但是,32位的switch_to却没有这个东东,我也很奇怪,所以继续往下找了一下linux-2.6.36的内核代码,发现后来也加了这个东西,arch/x86/include/asm/system.h里第一个switch_to的宏定义,有下面一段:


  1.    76                /* clobbered output registers: */        \
  2.    77                "=b" (ebx), "=c" (ecx), "=d" (edx),      \
  3.    78                "=S" (esi), "=D" (edi)               \
复制代码
可能是后来加的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP