疑问: 1. 进程切换时为什么rbp不像rsp那样存成Thread的成员而是通过压栈处理? 2. 进程切换完成后next进程的rip指向了`"popq %rbp"`, 它是如何接着上次的中断位置继续执行的? 3. 无法理解启动第一个进程的这句`"pushq %1\n\t"`, 因为此时rbp的值应是my_start_kernel的rbp, 这句又没给rbp赋新值, 有何意义?
Activity
mengning commentedon Sep 19, 2020
https://mp.weixin.qq.com/s/SzpN1BNty5aPDZhNdCO5yA
这里我写了一篇文章并配了视频,希望对您有帮助。
meilihao commentedon Sep 19, 2020
嗯. 抱歉, 我就是看完所有能找到的资料(包括上面的链接)都没法解答才问的.
mengning commentedon Sep 20, 2020
其实rip和rsp是CPU现场中最关键的两个,缺一不可,而rbp则不是最关键的,可以通过间接的方式处理,当然像rsp一样处理也可以工作,但为什么有通用的堆栈机制方法不用而采用特例呢?
rsp指向next进程的堆栈栈顶,而栈顶恰恰是"popq %rbp"
这一点你要理解函数调用堆栈框架,只是从头开始的进程栈底稍微特殊一点,空栈也就是rsp和rbp相同。
meilihao commentedon Sep 21, 2020
我对函数调用堆栈有基本的概念, 之前自学过一点反汇编. 通常函数开头都有这两句, 就是为了让rsp和rbp相同.
我反汇编my_start_kernel的结果是:
还是没看出
push %rdx与rbp有什么关系.mengning commentedon Sep 22, 2020
rdx应该是task[pid].thread.sp,也就是next进程的rsp,next进程是一个新程序,为空栈
因此这时要压栈rbp,那就直接压栈rsp就好了,这地方只是我自己的简便写法,实际Linux内核中启动一个新程序的做法要复杂的多。
meilihao commentedon Sep 22, 2020
"空栈也就是rsp和rbp相同", 这我理解, 但mykernel里的这个场景需要我们手动调整, 因为起先rsp和rbp都是my_start_kernel的. 我认为这段内嵌汇编应该实现让rsp与rbp相等. 但实际只是设置了rsp让它等于rdx,
push %rdx后, rbp还是不等于rsp呀, 因此还是有点懵.