I finally set up my first IDT and I have one question. Lets say that I want to handle the Division By Zero hardware interrupt. Can I simply create an IDT with one entry and then load it with LIDT? Do I have to take care of anything else?
Posted on 2007-02-03 02:30:49 by XCHG
I honestly don't know how the processor would react. Ideally, as long as your entry length in the IDTR is accurate... it should work. Realistically, well... I never tried it myself... and I don't know how happy the processor would be if a NMI was explicitly rejected... if at all possible. I always made sure that there were entries to my Interrupt Handler for the first 32 interrupts and the 16 standard IRQs.

To clear-up how I do things: All entries in my IDT point to the same Interrupt Handler, which in itself checks for the existence/installation of a Interrupt Service Routine for whatever interrupt is called via lookup table. If the ISR is installed, it is called. If the ISR is not installed, the Interrupt Handler "quietly" returns.

It just seems easier to have a little extra data (IDT, lookup-tables, etc...) instead of larger and redundant code in the ISR's. Moreover, it works like a charm when you are multi-tasking with context switches ;)
Posted on 2007-02-03 03:10:19 by SpooK
One more thing, some of exception interrupts have error code but the others don't. This can change stack parameters. be careful about that.
Posted on 2007-02-03 08:29:02 by Dite

One more thing, some of exception interrupts have error code but the others don't. This can change stack parameters. be careful about that.


Correct. A common solution is to have an "intermediate" Interrupt Handler that takes this into account before jumping to the actual/primary Interrupt Handler.

Interrupts without error codes (and Exceptions) have a "fake" error code pushed onto the stack. Interrupts with error codes simply jump to the Interrupt Handler.


;INT 0x08 issues error code by design
INT_08:
jmp ISR_HANDLER

;INT 0x09 has no error code, create a "fake" one to keep the stack consistent
INT_09:
push BYTE 0
jmp ISR_HANDLER


You could even add another push value that gives the number of the interrupt/exception.

If you dynamically create your IDT, you could easily add a filler instruction (e.g. two NOPs) to the intermediate Interrupt Handler of Interrupts that give error codes to keep the physical size of the handlers consistent. This way, you can make a loop function that creates a dynamic IDT by only needing the location of the first intermediate Interrupt Handler and adding a constant value for each reiteration/interrupt needed.
Posted on 2007-02-03 17:51:14 by SpooK
Okay, I got it. I set up an IDT with only one entry hoping that I could handle the Division by Zero interrupt and no dice! It crashed and restarted the machine. While some interrupts change the content of the stack, I assume that it is impossible to refer all interrupts to the same procedure that only has an IRET written for it right? Because it would pop CS and EIP off of the stack and if the last DWORD pushed onto the stack is the error code or whatever, the EIP would be set incorrectly. Is that right?

Thank you guys for helping me out.
Posted on 2007-02-04 02:31:56 by XCHG
Yes. That is the primary purpose of the method I presented above, to avoid stack corruption due to the intermittent existence of error codes.
Posted on 2007-02-04 02:36:06 by SpooK
I thought something looked funny about this post... looks like I mixed up my technical jargon :P

Interrupts are hardware generated.

Exceptions are software generated.

I have modified the post to reflect the correct usage of such terms ;)
Posted on 2007-02-04 04:36:48 by SpooK
Okay what if I create an infinite loop in the Interrupt handler having pointed all the Interrupts between 0x00 to 0x32 to the same Interrupt Handler? It should at least avoid the machine from crashing right?

Say something like this:

  __InterruptHandler:
    JMP    $
  ; -- ------------------
  ALIGN 8, NOP
  IDT:
    TIMES  50 DD 0x00080000, 0x00008E00
  IDT_END:
  IDTR:
    DW  (IDT_END - IDT) - 1
    DW  IDT
Posted on 2007-02-05 01:07:22 by XCHG

Say something like this:
Posted on 2007-02-05 07:41:14 by Dite
I have them in the IDT already with the TIMES macro. Right?
Posted on 2007-02-05 08:22:45 by XCHG
Those two parts are effectively redundant. I suggest just using the top one to help trim down on the fat...


Posted on 2007-02-05 13:47:47 by SpooK
Thank you so much Spook. I changed my IDT's layout and it works now. One question though: wouldn't it be better if I put the fixed information such as the descriptor of the interrupt handler in the IDT already with the TIMES macro? I mean I will be saving two MOVs right?
Posted on 2007-02-06 00:20:04 by XCHG

Thank you so much Spook. I changed my IDT's layout and it works now. One question though: wouldn't it be better if I put the fixed information such as the descriptor of the interrupt handler in the IDT already with the TIMES macro? I mean I will be saving two MOVs right?


Size vs. Speed... considering the limited size of the IDT... I would pick size (dynamic table)
Posted on 2007-02-06 11:56:10 by SpooK
Copy that commander. Thank you again Spook. Over and out.
Posted on 2007-02-08 00:37:54 by XCHG