- 论坛徽章:
- 1
|
我在看ULK第三章wicht_to宏时书上说
1. 把eflags和ebp寄存器内容压入prev所对应的内核栈栈顶:
pushfl
pushl %%ebp
2. 把esp的内容保存到prev->thread.esp中以使该字段指向prev内核栈的栈顶:
movl %5,%%esp
484(%eax)操作数表示内存单元的地址为eax内容加上484。
3. 把next->thread.esp装入esp。此时,内核开始在next的内核栈上操作,因此这条指令实际上完成了从prev向next的切换:
movl next->thread.esp, %%esp
4. 向prev->thread.eip存入标记为1的地址。当被替换的进程重新恢复执行时,进程执行我们下面标记为1的那条指令:
movl $1f, prev->thread.eip
5. 宏把next->thread.eip的值(绝大多数情况下是上面所述标记为1的地址)压入next的内核栈:
pushl next->thread.eip
注意体会,当next执行完了以后的函数后,会回到这个栈的位置,执行eip对应的那条指令。
6. 跳到__switch_to()函数:
jmp __switch_to
7. 如干程序执行后,当A将再次获得CPU时,它执行一些保存eflags和ebp寄存器内容内容的指令,这两条指令的第一条指令被标记为1:
1:
popl %ebp
popfl
问题:
其中第2,3步使用的的thread_struct->esp,我不明白thread_struct->esp不是应该放prev和next的用户态堆栈吗?它怎么会把esp放到了prev->thread.esp中,又怎么会把next->thread.esp装入esp。这里使用的都应该是内核栈啊,应该使用esp0才对嘛。
我自己也分析了一下,在使用switch_to时只可能是在内核态,第2步中把esp放t入prev->thread.esp中岂不成了用内核态堆栈指针覆盖了原来的用户态指针。
小第新手,希望大家帮我解释一下 |
|