I think I've found a bug in James Molloy's tutorial.
In the ISR and IRQ handlers, we see the code
Code:
%macro ISR_NOERRCODE 1 ; define a macro, taking one parameter
[GLOBAL isr%1] ; %1 accesses the first parameter.
isr%1:
cli
push byte 0
push byte %1
jmp isr_common_stub
%endmacro
%macro ISR_ERRCODE 1
[GLOBAL isr%1]
isr%1:
cli
push byte %1
jmp isr_common_stub
%endmacro
However, later, we see this structure:
Code:
typedef struct registers
{
u32int ds; // Data segment selector
u32int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
u32int int_no, err_code; // Interrupt number and error code (if applicable)
u32int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
} registers_t;
Here, int_no and err_code are 32 bits wide, but previously we pushed 8 bits! I can definitively say it's the macro which is wrong, because the CPU pushes 32-bit error codes, so the "dummy" error code should be 32-bits too. For consistency's sake we may as well keep the ISR number as 32 bits.
This is clearly a mistake because later in isr_common_stub, we see:
Code:
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
So in the macros, you must change "push byte" to "push dword".
The same bug is present in the next lesson, IRQs and the PIT.
I can't add it to the Known Bugs wiki article because I'm not in the appropriate group and I don't know what group to join or how.