linux 系统输入():“movl(%ebp),%ebp”是什么意思

mfuanj7w  于 2023-03-07  发布在  Linux
关注(0)|答案(1)|浏览(129)

在Linux2.6.11的Sysenter fast系统调用过程中,VDSO Package 器在进入Ring0之前使用pushl %EBP; MOVL %ESP, %EBP,表示使用了带EBP的用户态度栈地址https://elixir.bootlin.com/linux/v2.6.11/source/arch/i386/kernel/vsyscall-sysenter.S#L19
内核堆栈,ESP(即用户状态堆栈的地址)在后续进程中被压入内核堆栈,但随后在sysenter入口点中出现了MOVL (%EBP), %EBP。(https://elixir.bootlin.com/linux/v2.6.11/source/arch/i386/kernel/entry.S#L192)
此时EBP寄存器不应该指向内核堆栈吗?或者有其他解释吗?
我的理解是这个EBP还是指向用户栈的,此时的方法是将EBP指向用户栈中断前的状态。

vlju58qv

vlju58qv1#

EBP仍然指向用户空间栈,内核入口点还没有修改它,这就是为什么mov (%ebp), %ebp前面的注解说“从用户栈加载潜在的第六个参数”。
EBP是int 0x80 ABI中传递第6个参数的位置。这也是为什么在sysenter推送EBP之前运行的用户空间VDSO代码,然后将ESP复制到EBP,因此1.内核可以恢复用户空间堆栈指针,2.因此内核有一个指针指向那个不适合寄存器的参数。(6个参数加上EAX中的调用号)
sysenter itself覆盖ESP(使用MSR IA32_SYSENTER_ESP中的固定值)。Linux选择使用sysenter入口点中的加载来获取当前任务的内核堆栈,而不是在每次上下文切换时更新MSR。无论哪种方式,ESP的用户空间值都会被覆盖。
这种堆栈切换功能就是为什么只有在内核加载新ESP之后才会重新启用中断(sti)的原因(sysenter清除IF,在执行任何内核指令之前禁用中断)。
这就是为什么EBP不能保存第6个系统调用参数;sysenter入口点的ABI将其视为用户空间堆栈指针,堆栈顶部的项是第6个参数。

相关问题