百科问答小站 logo
百科问答小站 font logo



为什么系统调用时要把一些寄存器保存到内核栈又从内核栈恢复? 第1页

  

user avatar   bei-ji-85 网友的相关建议: 
      

题主的两个问题:

1. 为什么要保存寄存器?

因为函数调用就是要保存寄存器,这是ABI要求的,比如通常情况下ESI/EDI需要被调用者保护,所以系统调用如果用了寄存器,肯定是要保护的。

如果题主问的是:为什么要保存所有寄存器?原因有两个:一个是为了安全,因为即使那些不需要保护的寄存器,在运行时的改动都可能包含内核的信息,这对于内核来说,并不够安全,用户层的代码可能会通过这些寄存器反推出一些内核的信息(入口地址等等);另一个原因是历史习惯,因为早年的时候系统调用走的是软中断,软中断和硬中断某些入口代码是一致的,因为中断可能发生在代码的任何位置,所以必须要保存全部寄存器,所以系统调用的软中断也继承了这种方式。

2. 为什么是内核栈?

因为用户栈不可靠。操作系统的一个基本的设计原则就是尽量不要再内核里崩溃,那么这种情况下,如果用户栈即将溢出,那么用户代码产生一次系统调用,内核如果用用户栈保存数据(不切换SS)就会导致内核崩溃,而且用户也不清楚系统调用的栈开销,稳妥的方式是用内核栈(用户不可见,内核可见,内核可控)。

那么如果在系统调用之前就用用户栈保存,这样就没有内核层面的栈溢出风险了,这样好不好?答案是不好,因为用户层的代码是不受内核保护的,这就给第三方程序恶意程序(甚至就是这个用户程序逐级)一个机会去修改调用栈,虽然崩溃的不会是内核,但用户层面会崩溃,风险也大。而且,确实有一些小众的操作系统这么干,但不算主流。

况且万一内核就是希望访问某个寄存器,这个寄存器又恰好在用户栈,直接访问用户栈的风险太大。




  

相关话题

  Fuchsia OS可以从Cast OS保留数据升级,是否说明Fuchsia只是Linux套壳? 
  机械类的优秀答主为什么那么少? 
  大二学生,计算机科学与技术专业,学到数据结构和组原有点心态爆炸了,看不懂敲不出代码,还有救吗 ? 
  ISP给的100M带宽到底是怎么算的? 
  许多人认为「学计算机吃青春饭」,为什么还那么多人学呢? 
  图形方面的函数的参数为什么多用浮点? 
  如何用通俗的语言解释拓扑排序? 
  计算机那么好,为什么计算机专业出身的很多人毕业都转行不搞计算机了? 
  使用 open addressing 的 Hash 表载荷过高为什么会降低 CPU 的缓存命中率? 
  那些打破圆周率小数位计算的记录是怎么判断计算得正不正确的? 

前一个讨论
通用电脑CPU有无硬件乘法器或硬件乘加器?
下一个讨论
为什么不把push ebp和mov ebp, esp的操作通过硬件方式做进call指令中?





© 2025-03-29 - tinynew.org. All Rights Reserved.
© 2025-03-29 - tinynew.org. 保留所有权利