org 0x07c00 ; Start address 0000:7c00 jmp short begin_boot ; Jump to start of boot routine & skip other data bootmesg db "Our OS boot sector loading ......" pm_mesg db "Switching to protected mode ...." dw 512 ; Bytes per sector db 1 ; Sectors per cluster dw 1 ; Number of reserved sectors db 2 ; Number of FATs dw 0x00e0 ; Number of dirs in root dw 0x0b40 ; Number of sectors in volume db 0x0f0 ; Media descriptor dw 9 ; Number of sectors per FAT dw 18 ; Number of sectors per track dw 2 ; Number of read/write sectors dw 0 ; Number of hidden sectors print_mesg : mov ah,0x13 ; Fn 13h of int 10h writes a whole string on screen mov al,0x00 ; bit 0 determines cursor pos,0->point to start after ; function call,1->point to last position written mov bx,0x0007 ; bh -> screen page ie 0,bl = 07 ie white on black mov cx,0x20 ; Length of string here 32 mov dx,0x0000 ; dh->start cursor row,dl->start cursor column int 0x10 ; call bios interrupt 10h ret ; Return to calling routine get_key : mov ah,0x00 int 0x16 ; Get_key Fn 00h of 16h,read next character ret clrscr : mov ax,0x0600 ; Fn 06 of int 10h,scroll window up,if al = 0 clrscr mov cx,0x0000 ; Clear window from 0,0 mov dx,0x174f ; to 23,79 mov bh,0 ; fill with colour 0 int 0x10 ; call bios interrupt 10h ret begin_boot : call clrscr ; Clear the screen first mov bp,bootmesg ; Set the string ptr to message location call print_mesg ; Print the message call get_key ; Wait till a key is pressed bits 16 call clrscr ; Clear the screen mov ax,0xb800 ; Load gs to point to video memory mov gs,ax ; We intend to display a brown A in real mode mov word [gs:0],0x641 ; display call get_key ; Get_key again,ie display till key is pressed mov bp,pm_mesg ; Set string pointer call print_mesg ; Call print_mesg subroutine call get_key ; Wait till key is pressed call clrscr ; Clear the screen cli ; Clear or disable interrupts lgdt[gdtr] ; Load GDT mov eax,cr0 ; The lsb of cr0 is the protected mode bit or al,0x01 ; Set protected mode bit mov cr0,eax ; Mov modified word to the control register jmp codesel:go_pm bits 32 go_pm : mov ax,datasel mov ds,ax ; Initialise ds & es to data segment mov es,ax mov ax,videosel ; Initialise gs to video memory mov gs,ax mov word [gs:0],0x741 ; Display white A in protected mode spin : jmp spin ; Loop bits 16 gdtr : dw gdt_end-gdt-1 ; Length of the gdt dd gdt ; physical address of gdt gdt nullsel equ $-gdt ; $->current location,so nullsel = 0h gdt0 ; Null descriptor,as per convention gdt0 is 0 dd 0 ; Each gdt entry is 8 bytes, so at 08h it is CS dd 0 ; In all the segment descriptor is 64 bits codesel equ $-gdt ; This is 8h,ie 2nd descriptor in gdt code_gdt ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x0ffff ; Limit 4Gb bits 0-15 of segment descriptor dw 0x0000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x00 ; Base addr of seg 16-23 of 32bit addr,32-39 of sd db 0x09a ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor ; privilege level 0-3,Segment descriptor 1 ie code ; or data seg descriptor,Type of seg,Accessed bit db 0x0cf ; Upper 4 bits G,D,0,AVL ->1 segment len is page ; granular, 1 default operation size is 32bit seg ; AVL : Available field for user or OS ; Lower nibble bits 16-19 of segment limit db 0x00 ; Base addr of seg 24-31 of 32bit addr,56-63 of sd datasel equ $-gdt ; ie 10h, beginning of next 8 bytes for data sd data_gdt ; Data descriptor 4Gb flat seg at 0000:0000h dw 0x0ffff ; Limit 4Gb dw 0x0000 ; Base 0000:0000h db 0x00 ; Descriptor format same as above db 0x092 db 0x0cf db 0x00 videosel equ $-gdt ; ie 18h,next gdt entry dw 3999 ; Limit 80*25*2-1 dw 0x8000 ; Base 0xb8000 db 0x0b db 0x92 ; present,ring 0,data,expand-up,writable db 0x00 ; byte granularity 16 bit db 0x00 gdt_end times 510-($-$$) db 0 ; Fill bytes from present loc to 510 with 0s dw 0x0aa55 ; Write aa55 in bytes 511,512 to indicate that ; it is a bootable sector.