Do I have to call an error code that has been pushed onto the stack with some exceptions before returning from the interrupt handler?

I uploaded an idt table with 256 elements, all pointing to similar handlers:

  • for exceptions 8 and 10-14, click the exception number (these exceptions automatically click the error code)
  • for the rest, click the error code "dummy" and the exception number;
  • then go to the common handler

So, when a regular handler comes in, the stack is correctly aligned and contains an exception / interrupt number, an error code (which can be just dummy), eflags, cs and eip.

My question is about returning from an interrupt handler. I use iret to return after retrieving the exception number and error code from the stack, but this does not work for nr 8 exception; if I leave the error code on the stack, then it will return a fine!

Questions:

  • Do I need to leave an error code on the stack for exceptions that put an error code there? If so, how can iret determine whether it should cause an error code or not?
  • As soon as I turn on interrupts, I always get exception 8 (double error), but then everything works fine (I develop an OS hobby). Is this normal behavior or do I have a bug somewhere?
+6
assembly x86 interrupt operating-system osdev
source share
4 answers

If the CPU automatically popped an error code, the handler should place it before iret . The iret instruction iret not know where you are from if it is a bug, trap, or an external interrupt. It always does the same and assumes that there is no error code on the stack.

Quote from SDM (Guide for Software Developers), Volume 3, Chapter 5, Section 5.13 entitled Error Code:

The error code is pushed onto the stack as a double word or word (depending on the default interrupt, trap or task gate size). To maintain stack alignment for a double push, the upper half of the error code is saved. Note that the error code does not appear when the IRET statement is executed to return from the exception handler, so the processor must delete the error code before executing the return.

You can find the IA-32 Software Developer Guide here : http://www.intel.com/products/processor/manuals/

Volume 3, Part 1, Chapter 5, describes the handling of exceptions and interrupts. Volume 2, Part 1 has a specification for the iret team.

+12
source share

I wrote a small x86 operating system some time ago. Take a look at the isr.asm file in the cvs repository.

Pay attention to how we configure the handlers, most of them put a dummy dword on the stack to allow for several handlers that automatically receive an error code. Then, when we return via iret, we can always take 2 words on the stack regardless of interruption and add esp 8 before iret clears things well.

This should answer your first question.

As for your second question: a double error when triggering interrupts, ... hmmm could be a problem with the search call if you did not configure it correctly. There could be millions of other things :)

+1
source share

I had a similar problem with "double errors" as soon as I turned on interrupts. Well, they looked like double errors, but they really were timer interrupts!

Double errors are interrupt number 8 .

Unfortunately, by default, the PIC configuration signals the interrupt timer as an interrupt number (DEFAULT_PIC_BASE + TIMER_OFFSET) = (8 + 0) = 8 .

Disguising all my PIC interrupts (until I was ready to configure PIC correctly) disabled these interrupts with a double countdown timer failure.

(PICs require the CPU to acknowledge interrupts before they execute the next one. Since your code did not acknowledge the initial timer interruption, the PIC never gave you more! That's why you only have one, not a million, one might have expected.)

+1
source share

Should I leave the error code on the stack for exceptions that put the error code there?

As already mentioned, you should do the following:

 pop %eax /* Do something with %eax */ iret 

Or if you want to ignore the error code:

 add $4, %esp iret 

If you do not, iret interprets the error code as a new CS, and you will probably get general protection, as indicated in: Why does iret from the page error handler generate interrupt 13 (general protection error) and error code 0x18?

The minimal work with the handler of this page that I created to illustrate this. Try commenting on pop and see how it explodes.

Compare the above with a split error exception that should not cause the stack.

Please note that if you just int $14 , an extra byte will not be pressed: this only happens with the actual exception.

Intel Programming Guide Volume Guide 3 - 325384-056US September 2015 Table 6-1. The "Protected mode excluded and interrupted modes" column "Error code" contains a list of interrupts that cause the error code or not.

38.9.2.2 "Page Error Error Codes" explains what the error means.

The best way to deal with this is to introduce a dummy error code 0 on the stack for interrupts that do not do this to make things the same. The James Molloy tutorial does just that .

The Linux 4.2 kernel seems to do something similar. In arch / x86 / entry / entry64.S it models interrupts with has_error_code :

 trace_idtentry page_fault do_page_fault has_error_code=1 

and then uses it in the same file as:

 .ifeq \has_error_code pushq $-1 /* ORIG_RAX: no syscall to restart */ .endif 

which clicks when has_error_code=0 .

0
source share

All Articles