2
votes

I've read (and studied) about Interrupt Handling.
What I always fail to understand, is how do we know where to return to (PC / IP) from the Interrupt Handler.
As I understand it:

  1. An Interrupt is caused by a device (say the keyboard)
  2. The relevant handler is called - under the running process. That is, no context switch to the OS is performed.
  3. The Interrupt Handler finishes, and passes control back to the running application.

The process depicted above, which is my understanding of Interrupt Handling, takes place within the current running process' context. So it's akin to a method call, rather than to a context switch.
However, being that we didn't actually make the CALL to the Interrupt Handler, we didn't have a chance to push the current IP to the stack.
So how do we know where to jump back from an Interrupt. I'm confused.

Would appreciate any explanation, including one-liners that simply point to a good pdf/ppt addressing this question specifically.
[I'm generally referring to above process under Linux and C code - but all good answers are welcomed]

3
A bit pedantic, but point (2) above is not quite the way to say this. On interrupt, the core definitely switches "to the OS" in ring 0 kernel code. The core can service the interrupt without changing the CR3 page table pointer, so in that sense there is no context switch. User processes all map the global kernel page tables for this reason.srking
@srking: I'll be pedantic anew - it is clear the handler is registered with the OS. Also in any normal scenario the handler itself would be in the kernel address space. However, the running process would be kept running - so yup, no context switch. Moreover, any spent CPU cycles would be accounted under that process' accounting.Trevor

3 Answers

2
votes

It's pretty architecture dependent.

On Intel processors, the interrupt return address is pushed on the stack when an interrupt occurs. You would use an iret instruction to return from the interrupt context.

On ARM, an interrupt causes a processor mode change (to the INT, FIQ, or SVC mode, for example), saving the current CPSR (current program status register) into the SPSR (saved program status register), putting the current execution address into the new mode's LR (link register), and then jumping to the appropriate interrupt vector. Therefore, returning from an interrupt is done by moving the SPSR into the CPSR and then jumping to an address saved in LR - usually done in one step with a subs or movs instruction:

movs pc, lr
1
votes

When an interrupt is triggered, the CPU pushes several registers onto the stack, including the instruction pointer (EIP) of the code that was executing before the interrupt. You can put iret and the end of your ISR to pop these values, and restore EIP (as well as CS, EFLAGS, SS and ESP).

By the way, interrupts aren't necessarily triggered by devices. In Linux and DOS, user space programs use interrupts (via int) to make system calls. Some kernel code uses interrupts, for example intentionally triple faulting in order to force a shutdown.

0
votes

The interrupt triggering mechanism in the CPU pushes the return address on the stack (among other things).