操作系统篇章

今天在看《操作系统导论》时候复习了一下ucore中的上下文切换,相关代码如下:

void switch_to(struct context *from, struct context *to);
.text
.globl switch_to
switch_to:                      # switch_to(from, to)
 
    # save from's registers
    movl 4(%esp), %eax          # eax points to from
    popl 0(%eax)                # save eip !popl
    movl %esp, 4(%eax)          # save esp::context of from
    movl %ebx, 8(%eax)          # save ebx::context of from
    movl %ecx, 12(%eax)         # save ecx::context of from
    movl %edx, 16(%eax)         # save edx::context of from
    movl %esi, 20(%eax)         # save esi::context of from
    movl %edi, 24(%eax)         # save edi::context of from
    movl %ebp, 28(%eax)         # save ebp::context of from
 
    # restore to's registers
    movl 4(%esp), %eax          # not 8(%esp): popped return address already, eax now points to to
    movl 28(%eax), %ebp         # restore ebp::context of to
    movl 24(%eax), %edi         # restore edi::context of to
    movl 20(%eax), %esi         # restore esi::context of to
    movl 16(%eax), %edx         # restore edx::context of to
    movl 12(%eax), %ecx         # restore ecx::context of to
    movl 8(%eax), %ebx          # restore ebx::context of to
    movl 4(%eax), %esp          # restore esp::context of to

    pushl 0(%eax)               # push eip
 
    ret

switch_to里边前一半代码是将被切换进程的寄存器状态保存在栈里,后一半代码是将切换进程的相关寄存器状态从栈里恢复到寄存器中。

相关的tips

  1. popl 0(%eax)这条指令的含义是将栈顶的数据弹栈并赋值给eax寄存器,等价于
movl %esp, %eax
addl $4, %esp
  1. pushl 0(%eax)指令的含义是将%eax寄存器中的地址压栈,即赋值给栈顶寄存器esp,等价于
subl $4, %esp
movl %eax, %esp
  1. 在Linux系统中,进程的切换是在内核态完成的,也就是说此时的压栈弹栈操作用的都是内核栈,它的结构大概长这样:
    一个简单的内核栈示意图

内核栈是从高地址向低地址增长,如下图所示:简单的内核栈示意图

细看保存当前进程的寄存器状态

  1. 以上面(👆)的内核栈图示为例,栈顶指针esp指向地址为4的位置,那么4(%esp)指向地址为8的位置。则movl 4(%esp), %eax这条指令将栈顶指针加4的地址赋值给eax,此时eax寄存器里边存储的就是地址8
  2. popl 0(%eax)这条指令的含义实际就是让eax里边的值变为esp此时存储的地址4,然后esp + 4 = 8,此时内核栈的示意图如下:
    新的内核栈图示
  3. movl %esp, 4(%eax)这条指令将当前esp的地址8写在eax + 4 = 8的位置上,似乎和上一条指令的结果一样?
  4. 随后的指令分别将ebxecxedxesiediebp写在地址8之后,如下图所示:
    保存相关寄存器状态时的内核栈

恢复即将运行的进程上下文的过程,是和上面相反的情况,倒着看图就好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值