Skip to content

Commit

Permalink
翻译似乎有点和原文不符合
Browse files Browse the repository at this point in the history
  • Loading branch information
shaoliming committed Jul 12, 2019
1 parent 7249f34 commit 1a8e607
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion content/chapter5.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ xv6 必须为进程提供互相协作的方法。譬如,父进程需要等待

接下来我们先不考察调度器调用 `swtch` 的过程,我们先回到用户进程中看看。在第3章中我们知道,有可能在中断的最后,`trap` 会调用 `yield``yield` 又调用 `sched`,其中 `sched` 会调用 `swtch` 来保存当前上下文到 `proc->context` 中然后切换到之前保存的调度器上下文 `cpu->scheduler`(2516)。

`swtch`(2702)一开始从栈中弹出参数,放入寄存器 `%eax` 和 `%edx`(2709-2710)中;`swtch` 必须在改变栈指针以及无法获得 `%esp` 前完成这些事情。然后 `swtch` 压入寄存器,在当前栈上建立一个新的上下文结构。仅有被调用者保存的寄存器此时需要被保存;按照 x86 的惯例即 `%ebp %ebx %esi %edi %esp`。`swtch` 显式地压入前四个寄存器(2713-2716);最后一个则是在 `struct context*` 被写入 `old`(2719)时隐式地保存的。要注意,还有一个重要的寄存器,即程序计数器 `%eip`,该寄存器在使用 `call` 调用 `swtch` 时就保存在栈中 `%ebp` 之上的位置上了。保存了旧寄存器后,`swtch` 就准备要恢复新的寄存器了。它将指向新上下文的指针放入栈指针中(2720)。新的栈结构和旧的栈相同,因为新的上下文其实是之前某次的切换中的旧上下文。所以 `swtch` 就能颠倒一下保存旧上下文的顺序来恢复新上下文。它弹出 `%edi %esi %ebx %ebp` 然后返回(2723-2727)。由于 `swtch` 改变了栈指针,所以这时恢复的寄存器就是新上下文中的寄存器值。
`swtch`(2702)一开始从栈中复制参数,放入寄存器 `%eax` 和 `%edx`(2709-2710)中;`swtch` 必须在改变栈指针以及无法获得 `%esp` 前完成这些事情。然后 `swtch` 压入寄存器,在当前栈上建立一个新的上下文结构。仅有被调用者保存的寄存器此时需要被保存;按照 x86 的惯例即 `%ebp %ebx %esi %edi %esp`。`swtch` 显式地压入前四个寄存器(2713-2716);最后一个则是在 `struct context*` 被写入 `old`(2719)时隐式地保存的。要注意,还有一个重要的寄存器,即程序计数器 `%eip`,该寄存器在使用 `call` 调用 `swtch` 时就保存在栈中 `%ebp` 之上的位置上了。保存了旧寄存器后,`swtch` 就准备要恢复新的寄存器了。它将指向新上下文的指针放入栈指针中(2720)。新的栈结构和旧的栈相同,因为新的上下文其实是之前某次的切换中的旧上下文。所以 `swtch` 就能颠倒一下保存旧上下文的顺序来恢复新上下文。它弹出 `%edi %esi %ebx %ebp` 然后返回(2723-2727)。由于 `swtch` 改变了栈指针,所以这时恢复的寄存器就是新上下文中的寄存器值。

在我们的例子中,`sched` 调用 `swtch` 切换到 `cpu->scheduler`,即 per-cpu 的调度器上下文。这个上下文是在之前 `scheduler` 调用 `swtch`(2478)时保存的。当 `swtch` 返回时,它不会返回到 `sched` 中,而是返回到 `scheduler`,其栈指针指向了当前 CPU 的调度器的栈,而非 `initproc` 的内核栈。

Expand Down

0 comments on commit 1a8e607

Please sign in to comment.