I use NASM to compile pure assembly on Linux.
The program with pure assembly works with some things that looks like the PE Struct, as the definitions must be stored at the .data section, if is a variable, use .data?
the code starts at .code, i like to put an inline function named "start", but thats not necessary.
About the BootLoader,
i made a topic about that some years ago but it was in portuguese(im brazilian), if you want the link please PM me
The computers, when you turn them on, it automatically checks the first 512 bytes of the HD to see if it has an OS, if it finds an OS, it loads the this 512 bytes into the address 0000:7C00(HEX)(PS: YES, thats an relative address), another thing you should know, is that you'll always have to control the interrupts of the computer from you BIOS, you should check this website to know the interrupts list:
Interrupts List
If your OS has more than 512 bytes, the space that the hardware allocated for you wont me enough, so you'll need to have a loader, heres an example:
org 7C00h ;organize the offset
;inicialização da pilha
mov ax, 07C0h
mov ss, ax ;sets SS to 07C0
mov sp, 03FEh ;sets to the top of the stack
;seta segmento de dados
xor ax, ax
mov ds, ax ;sets the data segment to 0
;altera o modo de vídeo
mov ah, 00h ;subfunction to video
mov al, 03h ;03h = 80x25, 16 colors
int 10h ;video interrupt
;le dados do disquete
mov ah, 02h ;read subfunction
mov al, 1 ;number of sections to read
mov ch, 0 ;cylinder
mov cl, 2 ;sector
mov dh, 0 ;head
mov dl, 0 ;drive ( 00h = A: )
mov bx, 0800h ;ES:BX selects the memory location
mov es, bx ;where the data will be written
mov bx, 0 ;0800:0000h ( ES = 0800h, BX = 0000h )
jmp 0800h:0000h ;jump to the kernel location
After that you will need to build up a kernel, heres an example:
org 0000h
push cs
pop ds ;DS = CS
call clearscreen
lea si, Mensagem
mov ah, 0Eh
repetição:
mov al, [si] ;move para AL o caractere em SI
cmp al, 0h
jz terminou
int 10h ;video interrupt
inc si
jmp repetição ;repeat the loop untill finds 0
terminou:
mov ah, 0h ;wait for an ASync state
int 16h ;keyboard interrupt
mov ax, 0040h ;reboot method
mov ds, ax ;the value of 0040:0072h_
mov w.[0072h], 1234h
jmp 0FFFFh:0000h ;FFFF:0000h
clearscreen proc
pusha
mov ah, 06h
mov al, 0 ;cleans the screen
mov bh, 0000_1111b ;sets the collors
mov ch, 0
mov cl, 0
mov dh, 19h
mov dl, 50h
int 10h ;video interrupt
popa ;reput the values
ret ;returns the code
clearscreen endp