它们不一定与您在 ISR 的第一点中陈述的相同:中断是异步的,因此必须以某种方式“中断”主处理器的工作。
例如,让我们看看这个用地址修饰的 MIPS 代码,它没有任何用处:
4000. add $1, $2, $3
4004. sw $ra, 0($sp)
4008. jal subr # function call, sets $ra to 4012 and jumps to 4024
4012. lw $ra, 0($sp)
4016. jr $ra
4020.
4024. subr: sub $2, $1, $3
4028. jr $ra
这段代码可以从主处理器处理:算术运算(第 1、7 行)由算术单元完成,内存访问(第 2、4 行)由内存控制器完成,跳转(第 3、5、8 行)也是由主cpu完成的。(实际地址jal
是在绑定目标文件时设置的。)
这是用于函数调用。在任何时候都可以确定代码现在在哪里以及在下一个时间点执行哪些代码(即当程序计数器递增时:PC+=4)。
现在重点来了,当你的函数做了一些复杂的事情,但你仍然希望软件对击键做出反应时。然后一个所谓的协处理器开始发挥作用。这个协处理器一直等到某个事件(如键盘上的击键)发生,然后调用中断处理程序。这是位于内存中某个地址的代码块。
想想,处理器在上面的计算中,但同时你想在 address 上存储击键次数keys
。然后你编写一个从地址开始的程序0x80000180
(这在 MIPS 中定义为异常处理程序地址):
lw $at, keys
addi $at, $at, 1
sw $at, keys
eret
现在击键会发生什么?
- 协处理器知道击键
- 保存主处理器当前PC
- 主处理器的PC设置为0x80000180,执行中断代码
- 在
eret
PC 上设置为中断发生前主处理器的 PC
- 主程序的执行在那里继续。
这里在第 2 步和第 3 步之间从正常执行切换到中断处理,然后从第 4 步到第 5 步。
注意:我已经简化了很多,但应该清楚的是,中断与函数调用有何不同,以及硬件如何必须具有额外的中断处理能力。