I think your struct is off.
typedef struct {
uint32_t gs, ds, es, ds;
uint32_t edi, esi, ebp, ebx, edx, ecx, eax;
↑↑
uint32_t int_number, err_code;
uint32_t eip, cs, eflags, useresp, ss;
} isr_stack_frame_t;
The pushad
instruction pushes all eight GPRs in the opcode encoding order (eax, ecx, edx, ebx, esp, ebp, esi, edi). (Now looking at the tutorial linked, Bran also has esp
there.)
The other thing you are missing is the mov eax,esp
before push eax
and the call: the isr_stack_frame_t *
pointer you are passing to the IRQ handler is wrong in your case. You need to pass the actual frame address – which is the top (well bottom) of the stack since you just assembled it there using pushes.
But +2 for using .intel_syntax noprefix
– I'm not alone! \o/
As for “good Intel style” and, somewhat like @FrankKotler already said: never write mov eax,foo
; always write either mov eax,offset foo
or mov eax,[foo]
to leave no room for accidental confusion.
Another thing: you do not sti
directly before the iret
: The EI/DI (Interrupt) flag is stored in EFLAGS, which is restored by iret
anyway. So, just remove that line (Bran also doesn't have it).