2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理

以下实验内容来自educoder,通过实验获得更具体的认知
本阶段将学习中断/异常的响应和处理 ,学习系统调用的处理过程。

实验1

通过实际操作回答在输出第一行 0/1 字符的过程中(如下图所示),共发生了几次时钟中断?

跟踪分析时钟中断

等待 gdb 完全启动之后可以在函数 do_timer(由时钟中断的处理函数 timer_interrupt 调用)处设置断点;
让程序继续运行(使用命令 c ),分析在输出第一行 0/1 字符的过程中断点 do_timer 出现的次数,此即为时钟中断的次数。
通过全局变量jiffies可以直接查看已发生的时钟中断的次数。

中断/异常的恢复点分析

当一个中断/异常被 gdb 捕获时,通常正在运行中断处理程序,这时可以继续跟踪,直至回到恢复点指令。以时钟中断为例,为了从函数 do_timer 跟踪到恢复点,可以如下操作:
由上图可见时钟中断处理程序的入口是 timer_interrupt 函数。
跟踪到当前函数(do_timer)执行完毕返回到 timer_interrupt 函数;
跟踪到 timer_interrupt 函数(用汇编语言写的)末尾的 iret 指令;
si:Execute one machine instruction, then stop and return to the debugger.
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第1张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第2张图片

执行该 iret 指令,返回到恢复点;

在这里插入图片描述

通过反汇编命令:disas ,分析恢复点指令的地址。
在这里插入图片描述

实验2

本关任务:修改版本 1 内核源码,使得每次时钟中断发生时,都在屏幕上输出字符‘t’

时钟中断处理程序

时钟中断处理程序为 timer_interrupt ,每次时钟中断发生时都会执行此函数,此函数用汇编语言编写。
字符输出可以使用指令 int 0x81 ,该指令会输出一个字符到屏幕上,字符的 ASCII 码通过 AX 寄存器传递。
例如,为了输出的字符‘0’,可用如下指令:
在这里插入图片描述

判断已经发生了多少次时钟中断

已经发生的时钟中断的次数记录在全局变量 jiffies 中,每发生一次时钟中断,该变量的值就增加 1 。

实验3

通过相关知识回答下列问题:
1.在函数 main 的语句jiffies = jiffies/0;所对应的汇编指令片段中,有一个 idiv 指令,此指令的地址是多少?
2.在该 idiv 指令执行之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少?
3.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?(使用 gdb 调试内核,是为了跟踪到 main 函数入口)

响应中断/异常时,CPU 做了哪些工作

2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第3张图片
1.切换到核心栈,并在其中保存中断现场。
2. 转到中断处理程序去运行,并切换到核心态。
上图显示了栈中中断现场的结构,(OLD SS:OLD ESP) 描述了用户栈顶的位置,(OLD CS:OLD EIP) 描述了恢复点的位置。

如何查看当前栈顶的状态

可以使用命令 x 来查看:2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第4张图片
上面显示了栈顶的 5 个长字,是某异常发生时的中断现场,其中存储的用户栈顶的位置是 0x17:0x2573c ,存储的恢复点的位置是 0xf:0x7967 。需要注意的是,x86 中栈是从高地址向低地址方向增长的,这里的栈顶位置是 0x1fa0c

查看 C 语句编译之后对应的汇编指令片段

如果要查看某条 C 语句编译之后对应的汇编指令片段,可以在该 C 语句处设置断点,并跟踪到该断点,然后反汇编,所看到的当前指令之后的一段汇编指令就对应于该 C 语句。

例如,jiffies = jiffies/0;是文件 main.c 的第 147 行,可以如下方式查看:
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第5张图片
上面显示的汇编指令中,有一行前面有箭头标识,此即为当前指令,即马上将要执行的指令。

实验4

1.在 0 号进程执行 fork 系统调用中的陷入指令(int 0x80)之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少?
2.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?
3.此时栈中保存的恢复点位置和用户栈位置分别是多少?

跟踪到系统调用的陷入指令(int 0x80)执行之前

一般而言,可以在该系统调用处设置断点,跟踪到该断点,然后使用 si 命令单步执行到陷入指令。但是,对于 main 函数里的 fork 系统调用,不能这样操作(因为 gdb 有时断点设置不够准),可以先跟踪到前一行的 move_to_user_mode 语句,然后使用 n 单步执行,即可到达 fork 系统调用的开始,此时再反汇编disas,找到陷入指令
注:
finish:Continue running until just after function in the selected stack frame returns. Print the returned value (if any). This command can be abbreviated as fin.

问:版本 1 内核的第 6 次时钟中断发生时,断点和恢复点(指令地址)分别是多少?

断点指令和恢复点指令的分析

对于外部中断而言,恢复点指令是断点指令后一条。需要说明的是,loop 指令的功能是先将 ecx 寄存器减一,然后检查其值,如果其值非 0 ,则继续循环,否则中止循环,执行下一条指令。以如下指令为例:
在这里插入图片描述
其功能是:在地址 0x7977 处循环,每次 ecx 寄存器都减一,直到其值为 0 。因此,loop 指令的上一条有可能是它自己。

知识点网络整理:

2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第6张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第7张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第8张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第9张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第10张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第11张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第12张图片
2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理_第13张图片
在这里插入图片描述

你可能感兴趣的:(操作系统,linux)