What's wrong with this code, part 12 - Retro Bad Code

I was at a security tech talk last week discussing some fascinating stuff, and it reminded me of an interview question that my manager used to give to people who said that they understood x86 Assembly language.

I realized that it would make an interesting "retro" "what's wrong with this code" so, here goes.

 

When you're writing code for low level platforms (REALLY low level platforms), one of the first things you need to start handling is processor interrupts.  On the x86 family of processors, when an interrupt is generated (either hardware or software), the processor generates a trap frame with the following information (I may have the CS and IP backwards, check your processor manual):

Your code is now executing, but you're running on the application's stack.  So the very first thing that has to happen in your interrupt handler is that you've got to switch to your own stack (you need to do this because you don't know how much memory is remaining on the user stack - if you overflow the user's stack, you've got problems.

So you'd have to write code that switches from the user's stack to your kernel mode stack.

My boss used to use an example that was the system call dispatcher for a theoretical operating system, which maintained a 32bit pointer to the kernel mode stack in a global variable, I'll continue that tradition.

    <code to establish DS>    MOV    [Saved_SS], SS    MOV    [Saved_SP], SP    MOV    SP, WORD PTR [Dos_Stack]    MOV    SS, WORD PTR [Dos_Stack]+2    <code to dispatch off of the value in AH>

The problem is that there's a MASSIVE bug in this code.  And it's not because of the use of global variables for the saved SS and SP - assume that the reentrancy issues are handled in the <code to establish DS> section above.