[bits 16] switch16_to_32: cli ; disable interrupts until we finish setup, since the ; 16-bit interrupt vector will be invalid lgdt [gdt_flat_descriptor] ; load the GDT which defines the flat code and data segments mov eax, cr0 ; move the control register to eax so we can modify it or eax, 0x1 ; set the 1st bit to enable 32-bit pm mov cr0, eax ; write the modified control value back jmp i_gdt_code_segment:initialize32 ; far-jump to our new 32-bit code, forcing CPU to clear the pipeline of 16-bit instructions [bits 32] initialize32: ; Set up registers and stack once in 32-bit protected mode mov ax, i_gdt_data_segment ; point the segment registers to the new data segment in 32-bit mov ds, ax mov ss, ax mov es, ax mov fs, ax mov gs, ax mov ebp, 0x90000 ; update stack position to be at the top of free space mov esp, ebp call main32