Notice the pusha at the very beginning of the function? That means that basically all registers are going to have their contents restored when the function exits. Now the way to solve this problem is to as the very last thing that you do before calling the isr_handler function you should try pushing a pointer to the stack to the stack. That way you can access all of the registers from the isr_handler function. If you don't want the code that explains what I said then stop reading here.
Then you just rewrite the isr_handler function so that it looks like this
Code: Select all
void isr_handler( struct REGS_S *registers )
REGS_S looks like this
Code: Select all
/// The value of the registers when the interrupt is fired
struct packed REGS_S
{
DWORD ds; ///< DS when the interrupt fired
DWORD edi; ///< EDI when the interrupt fired
DWORD esi; ///< ESI when the interrupt fired
DWORD ebp; ///< EBP when the interrupt fired
DWORD esp; ///< ESP when the interrupt fired
DWORD ebx; ///< EBX when the interrupt fired
DWORD edx; ///< EDX when the interrupt fired
DWORD ecx; ///< ECX when the interrupt fired
DWORD eax; ///< EAX when the interrupt fired
}; // end regs_t
Then you can edit the values that are in the registers after the interrupt returns like this
and last but not the least change isr_stub to look like this
Code: Select all
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp ; save the current esp as a pointer to the register stack
push esp
call isr_handler
pop eax ; just get rid of the pointer from the stack
pop eax ; reload the original data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti
iret
Try all of that and see if that helps any.