Page 1 of 1

Help! I am stuck with my IDT + weird INVALID_OPCODEexception

Posted: Wed Dec 22, 2021 1:54 pm
by Levandar
I tried so many different IDT designs but this seems to cause some weird errors. I took some of this code from another post on this forum (Yes, yes, I know copying code is bad but I spent so long trying to write this thing). I modified the code a bit because it was triple-faulting due to page faults and/or general protection faults, and Now the exceptions I am getting are super weird; I don't get how an invalid_opcode can even happen here. If I missed out some info or otherwise violated forum etiquette, just tell me and I will correct it.

Code: Select all

global lngmd_start
extern kernel_main
extern gdt.data
section .text
bits 64
lngmd_start:
    mov ax, gdt.data
    mov ss, ax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
   ;cli
   call map_entries
   lidt [idt.pointer]
   sti
   ;call kernel_main
   ;int 0x00 
   jmp krnl_hlt


map_entries:
   mov rbx, idt
.map_exceptions:
   mov rdx, 0
   mov r8, exception_handler
   mov rcx, 32
   jmp .loop
.map_irqs_pic1:
   mov rdx, 1
   mov r8, isr_handler.pic1
   mov rcx, 8
   jmp .loop
.map_irqs_pic2:
   mov rdx, 2
   mov r8, isr_handler.pic2
   mov rcx, 8
.loop:
   mov rax, r8 
   mov word [rbx], ax
   shr rax, 16
   mov word [rbx + 6], ax
   shr rax, 16
   mov dword [rbx + 8], eax
   add rbx, 16
   dec rcx
   ;jmp krnl_hlt ;This statement would behave as intended and halt the kernel, printing "a2"
   jne .loop
   jmp krnl_hlt ; This statement causes INVALID_OPCODE, instead of printing "a2" then halting. Removing this statement causes the kernel to simply hang without any output
   test rdx, rdx
   je .map_irqs_pic1
   
   dec rdx
   test rdx, rdx
   je .map_irqs_pic2
   ret
idt:
.exception_0:
        dw 0
        dw 0x8
        db 0
        db 10001110b
        dw 0
        dd 0
        dd 0
; --------------------------------
; exceptions 1 - 30
; --------------------------------
.exception_31:
        dw 0
        dw 0x8
        db 0
        db 10001110b
        dw 0
        dd 0
        dd 0
.irq_0:
   dw 0
   dw 0x8
   db 0
   db 10001110b
   dw 0
   dd 0
   dd 0
; --------------------------------
; irqs 1 - 14
; --------------------------------
.irq_15:
        dw 0
        dw 0x8
        db 0
        db 10001110b
        dw 0
        dd 0
        dd 0
.pointer:
        dw $ - idt - 1
        dq idt

exception_handler:
   jmp krnl_hlt

isr_handler:
.pic1:
   mov ax, 0x20
   out 0x20, ax
   iretq
.pic2:
   mov ax, 0x20
   out 0xa0, ax
   iretq

krnl_hlt:
    mov dword [0xb8000], 0x0c320c61
    abbc:
   hlt
   nop
    jmp abbc

Re: Help! I am stuck with my IDT + weird INVALID_OPCODEexcep

Posted: Wed Dec 22, 2021 9:01 pm
by Octocontrabass
What are the contents of the CPU registers when the exception occurs?

Does the exception occur at an address within your kernel? If it does, where in your kernel is it?

Re: Help! I am stuck with my IDT + weird INVALID_OPCODEexcep

Posted: Thu Dec 23, 2021 12:46 am
by iansjack
An INVALID_OPCODE happens when your instruction pointer points to an address that is not a valid part of your code. (This could also cause other exceptions.) The most obvious reason for this is doing a ret or an iret to an invalid address. Judicious use of a debugger will track down the issue.

The reason that it is suggested that you don't copy paste code is that this means that you don't understand what you are doing. And, if you don't understand your code, how can you correct errors in it other than asking others to do so for you?

Re: Help! I am stuck with my IDT + weird INVALID_OPCODEexcep

Posted: Thu Dec 23, 2021 5:02 am
by Levandar
Never mind, I fixed it on my own. After like a couple hours more of debugging the loop, I realised the comments “exceptions 1-30” and “irqs 1-15” in the initialising data had to be replaced with actual code *facepalm*. I can’t believe I was so confused about such a dumb mistake, sorry for wasting everyone’s time lol. At least I now understand all the code since I spent Soo long debugging it, so at least that is good.