// .global exc0 .global exc1 .global exc2 .global exc3 .global exc4 .global exc5 .global exc6 .global exc7 .global exc8 .global exc9 .global exc10 .global exc11 .global exc12 .global exc13 .global exc14 .global exc15 .global exc16 .global exc17 .global exc18 .global exc19 .global exc20 .global exc21 .global exc22 .global exc23 .global exc24 .global exc25 .global exc26 .global exc27 .global exc28 .global exc29 .global exc30 .global exc31 .global int128 .global int129 .global int130 .global int131 .global int132 .global int133 .global int134 .global int135 .global int136 .global int137 .global int138 .global int139 .global int140 .global int141 .global int142 .global int143 .global int144 .global int145 .global int146 .global int147 .global int148 .global int149 .global int150 .global int151 .global int152 .global int153 .global int154 .global int155 .global int156 .global int157 .global int158 .global int159 .global int160 .global int255 // nothing to ack / macro .macro ack0 .endm // ack master pic / macro .macro ack1 push %eax // persist mov $0x20,%al out %al,$0x20 pop %eax // load original .endm // ack master and servant pic / macro .macro ack2 push %eax // persist mov $0x20,%al out %al,$0xa0 // slave out %al,$0x20 // master pop %eax // load original .endm // no error / macro .macro err0 .endm // exception with error / macro .macro err1 add $4,%esp .endm // interrupt / macro .macro intx ack num func /* Once we arrived here the stack already contains 3x 32bit values, which will be poped by 'iret' - eflags - return code segment selector - return instruction pointer There are two possiblities concerning our stack position: a) if the interrupt occured while kernel code was executed we are on the same stack and have no clue about the stack alignment b) if the interrupt occured while user code was executed the configured tss.esp0 was used, in this case we are at the start of the esp0 stack. */ \ack //acknowledge interrupt //also remember that we will get new interrupts only //after iret or reenabling themn explicitly! push $0x666 //make room for potential C functions 'return value'. //we use eax already for esp (so we can context switch) push $0x0 //indicate if we want to return the value in ebx 0x0=NO pusha //Push all standard registers 8 regs x 4bytes/32bit push %ds //Push data segment push %es //etc... push %fs push %gs mov %esp,%eax // remember THIS stack position and $-16,%esp // padding to align stack on 16byte boundary before CALL sub $8,%esp // ... push \num // pass in this interrupt number push %eax // pass in original %esp (saved just few lines before) call \func // call aligned mov %eax,%esp // use the %esp we got from c function pop %gs // pop everything back... pop %fs // ... pop %es pop %ds popa cmp $0x0,(%esp) je skip\num pop %ebx pop %ebx jmp ret\num skip\num: add $8,%esp // potentially set return value to eax to return to the caller ret\num: iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack .endm // cpu exception / macro .macro excx num err func cli // exception does not prevent from rescheduling, it seems? mov %esp,%eax // remember THIS stack position and $-16,%esp // padding to align stack on 16byte boundary before CALL sub $8,%esp // ... push \num // pass in this interrupt number push %eax // pass in original %esp (saved just few lines before) call \func // call aligned mov %eax,%esp // use the %esp we got from c function pop %gs // pop everything back... pop %fs // ... pop %es pop %ds popa cmp $0x0,(%esp) je skipEx\num pop %ebx pop %ebx jmp retEx\num skipEx\num: add $8,%esp // potentially set return value to eax to return to the caller retEx\num: sti iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack // pop %esp // \err //iret .endm exc0: excx $0 err0 exception_handle exc1: excx $1 err0 exception_handle exc2: excx $2 err0 exception_handle exc3: excx $3 err0 exception_handle exc4: excx $4 err0 exception_handle exc5: excx $5 err0 exception_handle exc6: excx $6 err0 exception_handle exc7: excx $7 err0 exception_handle exc8: excx $8 err1 exception_handle exc9: excx $9 err0 exception_handle exc10: excx $10 err1 exception_handle exc11: excx $11 err1 exception_handle exc12: excx $12 err1 exception_handle exc13: excx $13 err1 exception_handle exc14: excx $14 err1 exception_handle exc15: excx $15 err0 exception_handle exc16: excx $16 err0 exception_handle exc17: excx $17 err1 exception_handle exc18: excx $18 err0 exception_handle exc19: excx $19 err0 exception_handle exc20: excx $20 err0 exception_handle exc21: excx $21 err0 exception_handle exc22: excx $22 err0 exception_handle exc23: excx $23 err0 exception_handle exc24: excx $24 err0 exception_handle exc25: excx $25 err0 exception_handle exc26: excx $26 err0 exception_handle exc27: excx $27 err0 exception_handle exc28: excx $28 err0 exception_handle exc29: excx $29 err0 exception_handle exc30: excx $30 err1 exception_handle exc31: excx $31 err0 exception_handle int128: intx ack0 $128 interrupt_handler int129: intx ack0 $129 interrupt_handler int130: intx ack0 $130 interrupt_handler int131: intx ack0 $131 interrupt_handler int132: intx ack0 $132 interrupt_handler int133: intx ack0 $133 interrupt_handler int134: intx ack0 $134 interrupt_handler int135: intx ack0 $135 interrupt_handler int136: intx ack0 $136 interrupt_handler int137: intx ack0 $137 interrupt_handler int138: intx ack0 $138 interrupt_handler int139: intx ack0 $139 interrupt_handler int140: intx ack0 $140 interrupt_handler int141: intx ack0 $141 interrupt_handler int142: intx ack0 $142 interrupt_handler int143: intx ack0 $143 interrupt_handler int144: intx ack0 $144 interrupt_handler int145: intx ack0 $145 interrupt_handler int146: intx ack0 $146 interrupt_handler int147: intx ack0 $147 interrupt_handler int148: intx ack0 $148 interrupt_handler int149: intx ack0 $149 interrupt_handler int150: intx ack0 $150 interrupt_handler int151: intx ack0 $151 interrupt_handler int152: intx ack0 $152 interrupt_handler int153: intx ack0 $153 interrupt_handler int154: intx ack0 $154 interrupt_handler int155: intx ack0 $155 interrupt_handler int156: intx ack0 $156 interrupt_handler int157: intx ack0 $157 interrupt_handler int158: intx ack0 $158 interrupt_handler int159: intx ack0 $159 interrupt_handler int160: intx ack0 $160 interrupt_handler int255: intx ack0 $255 interrupt_handler