Original here: http://www.elhalf.com/bootsectors.txt
---------------
Bootsectors
---------------
-[El Half - http://www.elhalf.com]-



Introduction
----------------

When you power on your computer the BIOS does a Power On Self-Test
(POST). It then locates the first bootable drive (as defined
by the boot sequence in the BIOS menu).
Then the first sector on that drive is read (cylinder 0, sector 0)
and the instruction pointer (IP) is moved to the start of this code.
The boot sector has just been loaded into memory.
It is located at: 0000:7C00

All this is done in 16-bit real mode.
16-bit meaning that we have a 16-bit address space and thus we can
address only up to up to 0xFFFFF bytes (1024 kb) in memory.
Real mode means that we have no restrictions (obviously).

When writing a bootsector you have to keep in mind that you cannot
use OS interrupts. But we can use int 10h which is offered by the BIOS
to do something "useful"!

A bootsector always has to end with 0x55AA. In your code you will
define 0xAA55 because of the little/big endian thingy (don't know
which is applicable here...aren't I lame?)

Another thing to take in account is the size, make sure it doesn't
exceed 512 bytes. A real OS would obviously load an external kernel.
To do that you first need to write a filesystem, that which is not
covered in this text.


The code
-----------

This can be assembled with Netwide Assembler, which can be obtained freely
here: http://nasm.sourceforge.net

To assemble:
*****************************
C:\>nasm -o boot.bin boot.asm
*****************************

You can write the following code to a floppy by using elhalf.com/rawrite.exe
or if you don't trust me:
*****************************
C:\>debug boot.bin
-w 100 0 0 1
-q
*****************************

Restart your computer and boot from the floppy

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;BUG?: the string may get multiple times, or after the first time a B may appear
;I don't know why this is, if you know, please tell me ;)

[BITS 16]
[ORG 0x7C00]            ;BIOS puts us here
;16-bit real mode

jmp start

msg db 'Booting a shitty program',13,10,0

displaymsg:
lodsb                   ; load si string into al, similar (not entirely) to mov byte ptr al,ds:[si]
or al, al
jz return
mov ah,0eh              ; output character on screen function
mov bx,0007h            ; bl value = attribute (back/foreground colour), bh = pagenumber
int 10h                 ; we can't use OS interrupt obviously so we call int 10h
jmp displaymsg          ; loop

return:
ret

start:
;;;;;;;;;;;;;;;;;;;;
;let's make a stack;     Stack is not used so you can leave it away but I thought
;;;;;;;;;;;;;;;;;;;;     I'd include this because it is a common thing...

cli                     ;disable interrupts
mov ax, 9000h           ;we can't give this value directly to ss
mov ss, ax              ;location of stack
mov sp, 0h              ;stack pointer = 0
sti                     ;enable interrupts again
;end of stack creation

mov si,msg      
call displaymsg         ; display message


times 510-($-$$) db 0   ; we need to fill so the binary image will be 512 bytes
                        ; $ = start of instruction
                        ; $$ = start of program
dw 0xAA55               ; fills last 2 bytes with 0xAA55 which makes this a valid bootsector

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;