bits 16 ; mode 16bits org 0x7C00 ; mbr ae loaded at 0x7C00 jmp boot display_enable: push bp mov bp, sp mov ah, 0h ; 00h Set Video Mode mov al, 07h ; Txt, monochrome, 80x25 int 10h mov sp, bp pop bp ret print: push bp mov bp, sp mov si, [bp + 4]; put first function arg in si. sp is stask pointer .loop: lodsb ; load si content into al then inc si cmp al, 0; je .end mov ah, 0eh mov bx, 0 int 10h jmp .loop .end: mov sp, bp pop bp ret println: push bp mov bp, sp push word [bp + 4] call print add sp, 2 mov ah, 03h ; read cursor position int 10h ; row number in dh. Col in dl inc dh ; goto next line mov dl, 0 mov ah, 02h ; Set Cursor Position int 10h mov sp, bp pop bp ret hello db 'Hello world', 0 name db 'This is a name', 0 boot: sti ; enable virtual interupts call display_enable push hello call println add sp, 2 push name call println add sp, 2 ; Switch in 32bits Protected mode ; Activate A20 http://wiki.osdev.org/A20_Line to be able to access more than 1Mb memory mov ah, 0h mov ax, 0x2401 int 0x15 ; Change video mode to display VGA mov ax, 0x3 int 0x10 cli ; clear interruption flag ; switch in 32 bits lgdt [gdt_pointer] ; switch in 32bits here mov eax, cr0 or eax,0x1; set the protected mode bit on special CPU reg cr0 mov cr0, eax jmp CODE_SEG:boot2 ; GDT table desciption could be found http://wiki.osdev.org/Global_Descriptor_Table ; here we define the 3 64bits segment needed: null segment, code segment and data segment gdt_start: ;null segment dq 0x0 gdt_code: ;code segment dw 0xFFFF dw 0x0 db 0x0 db 10011010b db 11001111b db 0x0 gdt_data: dw 0xFFFF dw 0x0 db 0x0 db 10010010b db 11001111b db 0x0 gdt_end: gdt_pointer: dw gdt_end - gdt_start dd gdt_start CODE_SEG equ gdt_code - gdt_start DATA_SEG equ gdt_data - gdt_start bits 32 boot2: mov ax, DATA_SEG mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov esi,hello32 mov ebx,0xb8000 ; Cannot use BIOS anymore, use VGA Text buffer instead .loop32: lodsb or al,al jz halt or eax,0x0100 ; blue bg mov word [ebx], ax add ebx,2 jmp .loop32 halt: cli hlt hello32: db "Hello world!",0 times 510 - ($ - $$) db 0 ; fill up to 510 with 0 dw 0xAA55 ; MBR magic number