[bits 16] ; Sets up the GDT for the switch to 32-bit protected mode gdt_setup_flat: gdt_flat_null: ; mandatory null descriptor dd 0x0 ; dd means define double-word (i.e. 4 bytes) dd 0x0 gdt_flat_code_section: ; base: 0x0, limit: 0xfffff ; 1st flags: (present) 1 (privilege) 00 (descriptor type) 1 -> 1001b ; Type flags: (code) 1 (conforming) 0 (readable) 1 (accessed) 0 -> 1010b ; 2nd flags: (granularity) 1 (32-bit default) 1 (64-bit segment) 0 (AVL) 0 -> 1100b dw 0xffff ; limit (bits 0 - 15) dw 0x0 ; base (bits 0 - 15) db 0x0 ; base (bits 16 - 23) db 10011010b ; 1st flags, type flags db 11001111b ; 2nd flags, limit (bits 16 - 19) db 0x0 ; base (bits 24 - 31) gdt_flat_data_section: ; Same as code segment except for the type flags: ; type flags: (code) 0 (expand down) 0 (writable) 1 (accessed) 0 -> 0010b dw 0xffff ; limit (bits 0 - 15) dw 0x0 ; base (bits 0 - 15) db 0x0 ; base (bits 16 - 23) db 10010010b ; 1st flags, type flags db 11001111b ; 2nd flags, limit (bits 16 - 19) db 0x0 ; base (bits 24 - 31) gdt_flat_end: ; so the assembler can calculate the size of the gdt section gdt_flat_descriptor: dw gdt_flat_end - gdt_setup_flat - 1 ; size of our GDT, always less 1 of the true size dd gdt_setup_flat ; start address of the gdt i_gdt_code_segment equ gdt_flat_code_section - gdt_setup_flat i_gdt_data_segment equ gdt_flat_data_section - gdt_setup_flat