# x86 interrupts

## How intel architecture handles interrupts.

Let’s see how x86 interrupts work.

## Interrupts

There are three types of interrupts:

• Exceptions: synchronous with program execution.
Exemple: division by zero or invalid address access.

• hardware interrupts: asynchronous with program execution. They are generated by devices external to the CPU.
Exemple: key pressed

• software interrupts: synchronous with program execution. They are generated by x86 instructions such as int or syscall.
Exemple: int 0x80 - syscall

## Interrupt Description Table (IDT)

All the interrupts have a common interrupt vector called the Interrupt Description Table, commonly called the IDT.

This table can be seen as a C array of Interrupt Descriptors.

There are three types of interrupt descriptors:

• the Task Gate: it’s used for the tss, it will be describe in the next chapter about AtomOS.
• the Trap Gate: contains the routine to jump on.
• the Interrupt Gate: idem, but disable the hardware interrupts.

In fact, when the processor got a interrupt n, it will jump on the routine pointer contained in the interrupt descriptor at index n in the IDT.

### IDT register

An image is better than a long explication (It is almost the same with the GDT).

### Load the IDT

To load the IDT, you need to use the lid x86 instruction.

struct idt_s idt_reg;
idt_reg.base = (u32)idt_entry;
idt_reg.limit = sizeof(idt_entry) -1;

__asm__  volatile (
"lidt %0\n" ::"m"(idt_reg):"memory"
);

## Exceptions

The simpler type of interrupts is the exceptions, so let’s see how it works…

The 32 first intel interrupts are reserved for the exceptions. Here is a list of the x86 exceptions:

## Interrupt Subroutines (ISR)

### Context Switch

Most of the time in the i386 intel architecture, the interrupts routines are assembly wrappers which call the real routines. They are called Interrupt SubRoutines (ISR). Moreover, the context must be saved by the developer. Here is an example of exception ISR:

.globl no_error_wrapper
pusha
push $0 call error_isr add$0x04, %esp
popa
iret

.globl error_wrapper
error_wrapper:
pusha
call error_isr
popa
iret

You can remark that the no_error_wrapper calls the same routine than the error_wrapper. The difference is that it gives a fake error code.