;//--------------------------------------------------------------- ;// pmhello.s ;// ;// This bootsector program enters protected-mode, displays ;// a confirmation message, then returns back to real-mode. ;// It illustrates how to set up global descriptors for the ;// code, data, stack, and video-display memory-segmernts. ;// ;// programmer: ALLAN CRUSE ;// written on: 08 FEB 2004 ;//--------------------------------------------------------------- .SECT .TEXT ;----------------------------------------------------------------- start: cli ; enter critical section xor ax, ax ; address base segment mov ss, ax ; with SS register mov sp, #0x7C00 ; stacktp at BOOT_LOCN sti ; leave critical section jmpf #main, #0x07C0 ; re-normalize CS and IP ;----------------------------------------------------------------- .ALIGN 8 theGDT: .WORD 0x0000, 0x0000, 0x0000, 0x0000 ; null descriptor .WORD 0xFFFF, 0x7C00, 0x9A00, 0x0000 ; code descriptor .WORD 0xFFFF, 0x7C00, 0x9200, 0x0000 ; data descriptor .WORD 0x01FF, 0x7C00, 0x9600, 0x0000 ; down descriptor .WORD 0x7FFF, 0x8000, 0x920B, 0x0000 ; vram descriptor ;----------------------------------------------------------------- main: ; initialize system-register GDTR mov eax, #0x00007C00 ; address of this segment add eax, #theGDT ; base-address of our GDT mov bx, #0x0027 ; and GDT's segment-limit push eax ; push base-address push bx ; push segment-limit lgdt [esp] ; load GDTR register add esp, #6 ; discard triple-word ; enter protected mode cli ; disable interrupts mov eax, cr0 ; get machine status bts eax, #0 ; set PE-bit to 1 mov cr0, eax ; enable protection jmpf #pm, #0x0008 ; reload CS and IP pm: mov ax, #0x0018 ; address down segment mov ss, ax ; with SS register mov sp, #0x0000 ; set stacktop to zero ; write message to video display mov ax, #0x0010 ; address data segment mov ds, ax ; with DS register lea si, msg1 ; point DS:SI to message mov ax, #0x0020 ; address vram segment mov es, ax ; with ES register mov di, #320 ; point ES:DI to line #2 mov ah, #0x2E ; setup display-colors call dodraw ; draw string to screen ; restore suitable segment-attributes for real-mode mov ax, ds ; real-mode attributes mov es, ax ; in ES register-cache mov ss, ax ; in SS register-cache ; leave protected mode mov eax, cr0 ; get machine status btr eax, #0 ; reset PE bit to 0 mov cr0, eax ; disable protection jmpf #rm, #0x07C0 ; reload CS and IP rm: xor ax, ax ; address zero segment mov ss, ax ; with SS register mov sp, #0x7C00 ; stacktop at BOOT_LOCN sti ; interrupts enabled ; write message to video display mov ax, #0x07C0 ; address this segment mov ds, ax ; with DS register lea si, msg2 ; point DS:SI to message mov ax, #0xB800 ; address vram segment mov es, ax ; with ES register mov di, #640 ; point ES:DI to line #4 mov ah, #0x1F ; setup display-colors call dodraw ; draw string to screen ; await user keypress, then reboot xor ah, ah ; get_keyboard_input int 0x16 ; invoke BIOS service int 0x19 ; then reboot machine ;----------------------------------------------------------------- msg1: .ASCIZ " Hello from protected mode " msg2: .ASCIZ " OK, returned to real mode " ;----------------------------------------------------------------- dodraw: cld ; do forward processing nxchr: lodsb ; fetch next character or al, al ; is null terminator? jz drawx ; yes, exit this loop stosw ; else draw character jmp nxchr ; go back for another drawx: ret ;----------------------------------------------------------------- .ORG 510 ; boot-signature's offset .BYTE 0x55, 0xAA ; value of boot-signature ;----------------------------------------------------------------- END