# Interrupt return (ivss) **Interrupt return** restores the frame created when ivss delivers an interrupt. The assembler expands `iret` into four machine loads. The first restores the saved helper register thirteen: ```c Elf_PushByte(elf, PACK(OC_LOAD, MOD_LOAD_3)); Elf_PushByte(elf, PACK(IDX, SP)); Elf_PushByte(elf, 0x00); Elf_PushByte(elf, 0x04); ``` That encoding loads from the current stack pointer and increments it by four. The remaining generated instructions restore register twelve, `%status`, and `%pc` in that order. At handler entry, the automatic frame has this layout: ```text sp + 0: saved r13 sp + 4: saved r12 sp + 8: saved status sp + 12: saved next pc ``` The complete expansion consumes sixteen bytes. Any registers pushed explicitly by the handler must be popped first, so the stack pointer again identifies this frame. `ret` restores only a return address and therefore cannot replace `iret`. The actual ivss expansion is several instructions rather than one atomic machine operation; its final load transfers execution back to the saved program counter. Source: [asembler.c](https://github.com/yanevskiv/ivss/blob/main/src/asembler.c).