ORG 0x7c00 BITS 16 CODE_SEG equ gdt_code - gdt_start ; 0x8 DATA_SEG equ gdt_data - gdt_start ; 0x10 _start: jmp short start nop ; Setup dummy BIOS Parameter block so a dumb BIOS does not corrupt us ; if it starts messing up with the parameter block times 33 db 0 start: ; Set CS to 0 with label step2 as its beginning offset jmp 0:step2 step2: ; Setup segments cli ; Disable interrupts mov ax, 0 mov ds, ax mov es, ax mov ss, ax mov sp, 0x7c00 ; Stack segment starts right before ds ; and grows down to 0x0. This works because ; Intel implements a full descending stack sti ; Enable interrupts .load_protected: cli lgdt[gdt_table] mov eax, cr0 or eax, 0x1 mov cr0, eax jmp CODE_SEG:start_32 ; GDT table description gdt_start: gdt_null: ; First segment Descriptor is always 0 dd 0x0 dd 0x0 ;Second segment descriptor... Code segment - 0x8 gdt_code: dw 0xffff ; Segment limit 0-15 dw 0 ; Base address 0-15 db 0 ; Base 16-23 db 0x9a ; Access byte field 0b10011010 ; We don't have a 4 bits type, so use a byte type ; to set both Segment limit high bits and flags db 11001111b ; Segment limit 16-19 ; Flags 0-3 db 0 ; Base address high bits 24-31 ;Second segment descriptor... Data segment - 0x10 gdt_data: dw 0xffff ; Segment limit 0-15 dw 0 ; Base address 0-15 db 0 ; Base 16-23 db 0x92 ; Access byte field 0b10010010 db 11001111b ; Segment limit 16-19 ; Flags 0-3 db 0 ; Base address high bits 24-31 gdt_end: gdt_table: dw gdt_end - gdt_start - 1 dd gdt_start [BITS 32] ; No access to BIOS from now on.... start_32: ; Set all segments to the same as the DATA_SEG mov ax, DATA_SEG mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ; Set the stack pointer and base pointer further in mem mov ebp, 0x00200000 mov esp, ebp jmp $ ; Fill in to the end and add bootloader signature times 510 - ($ - $$) db 0 dw 0xAA55