二进制杂文(1) 中断

发布于 2021-08-07  85 次阅读


背景

经某自称需要把自己当作CPU才能学好二进制的大佬指点,看待很多问题有了新的角度,特此整理,因为各点之间几乎无联系,故为杂文

正文

标志寄存器的标志 置0或者置1本身是毫无意义的,他只是CPU用来瞄一眼的

这个观点在大多数情况下无用,一个比较特别的例子如下

进程PID 1和进程 PID 2同时发起中断,由于中断是最高优先级的指令,CPU需要优先处理

PID1和PID2发起中断的方式是寄存器中断标志位 置1,而非直接告知CPU需要中断(黑体部分很像是废话,但在本例当中很重要,先记住,我们继续说)

CPU在每个指令周期的第一个工作(除例行初始化外)是查看中断位(view brk R, VBR),第二个工作是重设看门狗(reset watchdog)

假设PID1和PID2同时发起的中断刚好在VBR之后,那么该中断请求只有下一周期开始时会被处理

假设现在已经进入了下一周期,则需要进行中断队列判优,大概是这样

判优算法笔者不清楚,这里oop一下就好,假设使用的函数是foo()就行,

foo会操作IRQ置1,然后向INVEC告知PID,进行相关中断操作,然后经由INACK发送feedback响应至源

这里可以发现,两点,一个是虽然中断是最高优先级的异常,但各种中断的优先级各自不同,中断的到达的先后顺序与中断在队列中的位置无关,另一个是CPU处理中断与IRQ真值有关,而非进程直接与CPU请求中断,理解第二点很重要,我可以举一个其他例子

比如我们不应该吧jmp 401000理解为让CPU的下一条执行指令变为401000处的指令

而应该理解为 mov EIP,401000(实际上mov并不能修改EIP)

也就是说所有的指令都并非真的是直接请求CPU进行某种操作,不过其他指令我们不考虑,主要是中断的外在显露比较强

好,我们回到中断上

IRQ置1还有一个很重要的硬件级功能:在IRQ接收到信号后,接受此后的第一个invec信号,然后屏蔽所有INVEC信号直到CPU退出中断模式

当判优器一眼瞟过去,看见多个优先级相同的中断是有可能的,按照某种算法给出IRQ与INVEC后,CPU为了避免相同优先级的其他IRQ干扰,会暂时屏蔽INVEC引脚

然后是中断和异常的区别和关系,看了很多资料之后,笔者目前倾向于把这两个东西看做一个东西,本质相同而外在不同的东西非要分成不同子类,太像是文科干的事情了

总的来说这两个东西(还包括trap什么的)的处置函数全都映射在同一张表上(IDT)

另外还需要注意的是,允许多线程同时运行的现代操作系统和现代CPU对中断处理的一个特点是异步性,引用一段话来解释这一点:

Operating Systems: Three Easy Pieces

定时器可以被编程为每隔多少毫秒引发一次中断;当中断被引发时,当前运行的进程被停止,操作系统中预先配置的中断处理程序运行。此时,操作系统其实已经重新获得了对CPU的控制权