[Home]  [Edit this page]  [Recent Changes]  [Special Pages]  [Help
x86ASMFAQ_INT
What are interrupts? How do they work?

There are three types of interrupts: CPU-generated, hardware-generated, and software-generated.

A CPU generated interrupt occurs when CPU does something wrong that needs to be fixed immediately, for example dividing by zero causes a CPU-generated interrupt. When a divide by zero happens, the CPU automatically jumps to an interrupt handler that will (hopefully) handle the problem. In this case, it may terminate the application and notify the user that a divide by zero has occured.

A hardware generated interrupt is generated by a peripheral, like the keyboard or the harddrive controller. These are also called IRQs. A hardware generated interrupt signals the CPU that some hardware needs to be serviced, for example the keyboard has a key. When they occur, the CPU will finish up whatever opcode it is working on, then jump to the interrupt handler (also called an interrupt service routine, ISR) for that interrupt. The ISR will placate the hardware then return to whatever the CPU was doing.

Finally, software generated interrupts are not interrupts at all. They are merely glorified function calls and are commonly used to access operating system services.

What is the IVT/IDT?

IVT stands for Interrupt Vector Table, and IDT stands for Interrupt Descriptor Table. The IVT is used in real-mode and the IDT is used in protected-mode. As the only time you should ever touch the IDT is if you are writing an OS from scratch, it won't be discussed here. However, it's the same idea conceptually.

The IVT is located at address 0000:0000 in real-mode (note: it can be moved starting with the 80386, but that's rare). The IVT is the mapping of interrupt numbers to interrupt handlers. In effect and actuality, it's simply a jump table. Each four bytes corresponds to the address of a function.

How do I hook an interrupt?

Just as a jump table can allow you to dynamically change the behavior of a program, the same can be done to the IVT. By changing an entry in the IVT you can have your own code handle an interrupt. Of course, before you go changing entries in the IVT there are some things you need to watch out for, these can be avoided by using an OS service to do this for you (and it's being nice to the OS to let it know). Basically, unless you use 32-bit opcodes, it will take two steps to change an IVT entry. The problem is that an interrupt could come along between those two steps, which would be a bad thing. The solution is simply to do it in one 32-bit move, or to turn off interrupts shortly.

It's good practice to save the old IVT entry and restore it when you are done, and unless you are completely replacing the functionality of that interrupt, you likely will want to call the old interrupt handler from your interrupt handler. In effect, you will create a chain of interrupt handlers.

If you hook an interrupt that is triggered, directly or indirectly, by the CPU or hardware, then you've now entered the world of asynchronous programming which introduces a whole set of problems. However, generally if you keep your interrupt handlers small, simple, quick, and self-contained, you won't have many problems.

Note that in a Win9x DOS box, direct IVT modifications are ignored. Instead, you must use functions 25h and 35h of INT 21h to read and write vector entries.

There was no mention of the IDT as you never need (or simply can't) hook the IDT. Either your running at application level and can't change it, or you are making a device driver and you need to work with the OS anyways, or you wrote the OS, in which case you put the initial values in the IDT and so it already goes to code you control. The only code I've seen that "hooks" the IDT is the CIH virus, and that's more a testament to Win95's horrible design.

What is an IRQ?

IRQ stands for Interrupt ReQuest and there is typically 16 IRQs, two groups of 8, numbered from 0 to 15. IRQs correspond to interrupt pins on the PIC and they are for hardware-generated interrupts. When servicing an IRQ as well as anything else you need to do, you need to reset the PIC before you return. You can reset the PIC by sending 0x20 to port 0x20, if you are servicing one of the higher IRQs (>8), then you'll also need to send 0x20 to port 0xA0.

Where can I get a list of INTs?

Ralph Brown's Interrupt List is a comprehensive list of all the interrupts. This is most useful for DOS real-mode programmers.

last edited (March 16, 2003) by ericj2190, Number of views: 4051, Current Rev: 5 (Diff)

[Edit this page]  [Page history]  [What links here]  [Discuss this topic]  [Printer Friendly]  

Members

Username:

Password:


Register
Forgot Password?




Programmers Heaven - for .NET, Java, C/C++ and WEB Developers!
© 1996-2008 Community Networks Ltd. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Tore Nestenius at .NET Consultant - Synchron Data.