1

阻塞是一种被动行为,是在请求IO资源时,发生的等待。 IO资源拿到后,自动加入就绪任务队列,等待分配CPU。

从阻塞到运行:不知道。

从就绪到阻塞:进程因为得不到io资源才进入阻塞,而请求io必须需要cpu ,所以不可能什么都不做就进入阻塞了。

2

当中断发生时,计算机会干什么?

  1. 中断硬件将现在的程序计数器,程序状态字,寄存器数值压入堆栈。(硬件)

  2. 指针跳转到中断向量表对应的中断地址的内存。(硬件)

    ​ 中断向量表保存的是各个中断处理程序的地址,而跳转最终的目的地是中断处理程序的首地址。

  3. 中断服务例程接管剩余的工作:(软件)

    1. 保存寄存器的值至进程的表项中。
    2. 删除硬件保存在堆栈的第一步的信息。
    3. 将进程指针指向一个新的临时堆栈。
    4. 调用c中断服务例程。
      1. (typically reads and buffers input).
    5. 调用调度程序,决定随后运行哪个进程。
    6. 调用汇编语言程序,为当前进程转入寄存器值和内存映射,并启动程序。

想要使用硬件代替软件,即将第三步的1-4步变为硬件完成的。

  1. 第一步,第三步的1-2步应当合为一步:设计一种向量表,直接保存所有进程的表项的开始地址,当需要调度程序时,直接将对应的计数器和psw,寄存器数值压入。

    但是,写到这里问题来了,这样子做势必会增大缓存的容量,而容量和速度不可兼得,所以cpu会花很长,很长的时间来等待程序的调度,得不偿失。

3

pg 53:一些诸如保存寄存器值和设置堆栈指针等操作,无法用c语言这类高级语言描述,所以这些操作通过一个短小的汇编语言例程完成,通常该例程可以供所有的中断使用,因为无论中断是怎样引起的,有关保存寄存器的工作则是完全一样的。

Actions such as saving the registers and setting the stack pointer cannot even be expressed in high-level languages such as C, so they are performed by a small assembly-language routine, usually the same one for all interrupts since the work of saving the registers is identical, no matter what the cause of the interrupt is.

英文版 pg 95。

4

网络上给出的答案是:

  • 首先,不希望操作系统崩溃,由于某些用户程序不允许足够的堆栈空间。
  • 第二,如果内核将数据保留在用户空间,然后从系统调用返回,那么恶意的用户可能使用这些数据找出某些关于其它进程的信息。[^1]

对于第一点,nswcfd在 内核堆栈意义?这篇帖子的2楼中说的比较明白:

  • user space stack overflow直接影响kernel stack,风险太大

而对于第二点,amarant在7楼进行了说明:

  • 用户对自己的sp有写的权利,如果内核使用用户栈,那么用户可以安排一个sp给kernel用。

此外:进程的堆栈 每个进程都有一个内核栈吗这两个讲的挺详细的,推荐去看。

假设用户态的堆栈过小,容易栈溢出,访问非法内存,导致系统崩溃。

在用户态,用户可以对堆栈寄存器进行操作,不安全。

5

[^1]: 《现代操作系统(中文第四版)》课后习题答案 第二章 进程与线程

相关文章
评论
分享
Please check the post_relate setting in config.yml of hexo-theme-Annie! You should make sure 'postsEnable == true' and the number of site posts greater than 1.
Please check the comment setting in config.yml of hexo-theme-Annie!