If the processor encounters an exception while trying to invoke an exception handler, a DOUBLE FAULT exception occurs. This can rarely occur, but is possible. For example, if the invocation of an exception causes the stack to overflow, then this would cause a double fault. This is a bad example of a double fault, because the same condition that caused the double fault obviously still persists, and the CPU will fail to invoke the double fault exception handler. When this happens, the CPU will triple fault and cause a SHUTDOWN cycle to occur. This special cycle should be interpreted by the motherboard hardware, who then pulls RESET, which ultimately resets the CPU and the computer.
Triple faulting the CPU can be useful for testing purposes, and in production code. Generating a triple fault is useful for test purposes to test that the special SHUTDOWN cycle is recognized by the hardware, and appropriately resets the CPU. In production code, triple faulting the CPU is an effective way to force the CPU out of protected mode. Since the 80286 has no way of exiting protected mode, IBM defined a keyboard controller command to reset the system. Unfortunately the keyboard controller responds slowly to the command and the reset takes many hundred micro-seconds. Triple faulting the CPU is about 1/3 faster than using the keyboard controller method (your mileage may vary depending on how and where you drive).
Understanding how to triple fault the CPU leads to writing elegant assembly language code that will take both the 80286 and 80386 (and above) out of protected mode in the manner best suited to each. Unlike the example stated above, there is a very elegant way to triple fault the '286, while simply returning the '386 from protected mode in its native manner. To do this, we need to first generate a DOUBLE FAULT, and guarantee that its generation will cause the desired TRIPLE FAULT. Easy! Load the interrupt descriptor table register (IDTR) with a value whose limit=0. Then generate an interrupt! Loading IDTR with a value whose limit=0, will guarantee that the invocation of ANY interrupt will triple fault the CPU. The CPU won't be able to service the first interrupt because the limit is too small. This itself causes an interrupt -- DOUBLE FAULT. Since the same condition still persists, a TRIPLE FAULT occurs, and resets the CPU. How do you do this in practice?
View source code for elegant reset:
Download entire source code archive for Elegant Reset:
Back to Productivity Enhancements