A subroutine is called by a program instruction to perform a function needed by the calling program. While Interrupt is initiated by an event such as an input operation or a hardware error. But how does the processor differentiate between them?
3 Answers
To add to the other good answers, I'm going to speak more to the logical similarities of function calling vs. interrupts, and then how those differ as well.
From a logical perspective, a subroutine or function call suspends the currently executing caller and transfers control to the sub/func. When that sub/func is finished, it returns control to the caller and it resumes after the call it made.
That is from a logical perspective — however, as far as the hardware is concerned there is no suspension or resumption or transfer of control from caller to callee — there is just a continuous execution stream of machine code instructions that happens to include various kinds of branching instructions, like call
(jal
e.g. on MIPS) and ret
(jr
)
The transfer of control from caller to callee happens under very controlled circumstances — a lot of this by software agreement, the ABI and the calling convention specified in the ABI. Caller and callee, by software convention have agreed in advance how parameters are passed, return values transferred back, and what registers are free for the callee to clobber vs. what register that, if used, it must preserve/restore upon return. Transfers of control from caller to callee happen at call sites and return sites, which are under program control — they happen synchronously as the result of executing instructions of the program.
When an interrupt happens, it could happen as if between any two instructions — so for one, there is no "calling convention" to govern the transfer from, say, user code (what is being interrupted) to the exception handler. With regard to external interrupts, the exception handler doesn't fully understand the code that was interrupted (the interrupted code is not attempting to make a synchronous call to the operating system). In this situation, all processor state such as registers must be presumed to be busy/in-use in the interrupted code, which has basically been forcefully suspended by transferring control to the exception handler.
External interrupts don't return values to the code that was interrupted — they change operating system state (device status), which may make some other process(es) go from blocked to runnable.
Because external interrupt may occur between any two instructions (unlike calls where the software can see the points of suspension/resumption), in order to make the thread resumable, (compared with function calls) more processor state needs to be preserved just in case the interrupted thread should later be read that state.
Even though modern hardware has many instructions in flight at any point in time, it has to preserve the illusion that the interrupt occurred in between two (dynamically) adjacent instructions. In part, this is so that it can indicate the program counter / instruction pointer within the interrupted program, of where to resume it.
As a result of external interrupts, the operating system's state changes. As a result of these changes, the operating system, upon returning from interrupt, may choose to resume a different thread than the one interrupted (in another process even), leaving the interrupted thread in a suspended state for later resumption. In this manner, scheduling and interleaving of threads may occur, which is substantially different (logically speaking) from function calling and function returning to caller. (Some user level systems have coroutines and fibers which exhibit transfer of control other than from caller to callee and back.)
In summary, function calling is done under control of the program, only at controlled points, and facilitated by software calling conventions and certain user-mode call and return instructions. However, to be clear, calling and returning can be done without these dedicated call and return instructions (they can be simulated by alternative instruction sequences without difficulty). Whereas external interrupts are triggered by an external device signaling the processor, may occur as if between any two instruction in the interrupted code, and in part because they involve privilege changes, requires a privileged instruction to resume from interruption & suspension that would be difficult or impossible to simulate with other, regular instructions.

- 23,049
- 2
- 29
- 53
-
Most external **hardware interrupts** may happen between two instructions only, but `x86` allows long string instructions, such as `REP MOVS`, `REP STOS`, be interrupted while this instruction is not finished yet. The state of elaborated string instruction is preserved in the saved contents of `rCX,rSI,rDI`. – vitsoft May 08 '21 at 06:28
-
1@vitsoft The same is true for Z80's LDIR (LoaD-Increment-Repeat), LDDR, etc instructions, which effectively implement a built-in loop. – tum_ May 08 '21 at 07:20
Obviously running a call
instruction invokes completely different behaviour than interrupt handling. (e.g. x86 https://wiki.osdev.org/Interrupts, and When an interrupt occurs, what happens to instructions in the pipeline?). The CPU switches into kernel (supervisor) mode to handle interrupts, on CPUs that have separate privilege levels.
After that, the CPU doesn't care how it got into its current state. The CPU just executes instructions; it's up to the programmer (of the OS or the subroutine) to put useful instructions there, e.g. on x86 ending with ret
(normal return) or iret
(interrupt-return).
ret
is not "special", on x86 it just pops a return address from the stack into the program counter. You can do the same thing other (usually slower) ways. iret
also has well-defined behaviour, not magic, and could perhaps be emulated with the right combination of popf
and far ref [rsp]
or other instructions, or maybe not depending on GDT entries. It's still not magic, though, just an instruction that makes specific changes to the architectural state (e.g. switching back to user mode, out of supervisor mode)
Things are similar on other ISAs; different instruction names, and different ways for the CPU to save enough state for the kernel to be able to return to user-space after interrupts.

- 328,167
- 45
- 605
- 847
This differs from CPU to CPU:
On some CPUs there was no difference (with the exception that the interrupt was initiated by some hardware event):
Both the call
instruction and the interrupt pushed the address of the next instruction to the stack and entered the function or interrupt handler. The ret
instruction was used to return from the function or interrupt.
If I remember correclty, the i8080 from the mid 1970s is an example of such a CPU.
On other CPUs, there is a huge difference between both:
In a function call, only the address of the next instruction is stored while all CPU registers are stored when entering an interrupt.
As a result, there are different instructions for returning from a function (ret
on x86) and for returning from an interrupt (iret
on x86). This is neccessary because leaving the interrupt works differently than leaving the function.
The MC6800 (also a mid-1970 chip) is an example of such a CPU.
Most CPUs (including x86) are somewhere in between these two variants.
There are even CPUs that require different instructions to return from from different types of interrupts (some PowerPC variants have four different instructions for returning from an interrupt)!
And there is Cortex-M where entering the interrupt and entering a function works completely differently but the same instruction can be used to leave the interrupt and the function (although leaving the function works differently than leaving the interrupt)...

- 17,897
- 3
- 19
- 38
-
1`all CPU registers are stored when entering an interrupt` That may be true for some architectures, but on many CPUs the programmer writing the ISR is responsible for saving the registers. It's not done by the CPU automatically. https://wiki.osdev.org/Interrupt_Service_Routines `iret` is required because the x86 saves the `EFLAGS` in case of an interrupt which takes extra space on the stack as oposed to a normal `ret` https://pdos.csail.mit.edu/6.828/2008/readings/i386/s09_06.htm but that also depends on the CPU and may have to be done by the programer as well. – Devolus May 07 '21 at 16:48
-
@Devolus This is why I wrote: "Most CPUs (including x86) are somewhere in between these two variants." – Martin Rosenau May 07 '21 at 17:24