Why loading GDT in the following way works

87 views Asked by At

I'm writing my own kernel and used this code to override global descriptor table set by bootloader. This is done in 32 bit protected mode.

flush_gdt:
    lgdt [gdtr]
    jmp 0x08:complete_flush
 
complete_flush:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    ret

The code works fine however I'm not able to understand why next instruction after lgdt is executed properly.

As far as I understand values of segment registers (especially CS) remain unchanged. Therefore CPU will use old register and new table to resolve address of instruction jmp 0x08:complete_flush. Chances are that entry in my table pointed by value of old CS is not a valid code segment and this would lead to crash. However nothing like this happens. Why?

EDIT: Asking this because my understanding is that CPU resolve linear addresses using CS:EIP registers pair. Now after lgdt CS would suddenly point to diffrent entry so why next instruction executed is the jmp instruction

0

There are 0 answers