Assembleur : boot sector
Boot Sector
CONTINUER PAGE 22 (à "Nurse, fecth me my...")
Cette page est issue de ma lecture de
<pdf>Fichier:Os-dev.pdf</pdf>
et me servira à y stocket mes programmes au fur et à mesure
Préambule à l'exécution de ce bazar
Chacun de ces programmes peut être compilé avec nasm:
nasm programme.asm -f bin -o fichierdesortie.bin
Puisque l'on écrit ici des secteurs de boot, on peut les exécuter avec qemu, ce qui est sympa:
qemu-system-x86_64 fichierdesortie.bin
J'utilise qemu sur manjaro, installable via
pacman -S qemu-full
Programmes
Boucle infinie <source lang='asm'>
- A boot program to be loaded onto a boot sector (yay !)
- loops forever
loop: ; A label to jump to
jmp loop ; The jmp cpu instruction simply jumps to ; a new memory address. Here, jump to the current ; instruction
times 510-($-$$) db 0 ; So apparently this tells the compiler to pad ; the program with zeroes, enough so it takes us ; to the 510th byte ; $ refers to the current address ; $$ refers to the address of the start of ; the current section ; times simply repeats the instruction x times ; db initialises memory with the number it's ; given
dw 0xaa55 ; The last two bytes are the magic number </source>
Afficher un message <source lang='asm'>
- A boot program to be loaded onto a boot sector (yay !)
- It prints something using interruptions
mov ah, 0x0e ; ax == 0x0e00 We store the value for the "scrolling teletype" BIOS ; routine into the ax register's high bit (hence the al and not ax)
mov al, 'C' ; The lowest bit receives the ascii code of the character to print int 0x10 ; Calling the interruption mov al, 'h' ; we keep going... int 0x10 mov al, 'a' int 0x10 mov al, 't' int 0x10
- Padding, magic number
times 510 -( $ - $$ ) db 0 ;fill the rest of the boot sector with zeroes dw 0xaa55 ; end with a magic number </source>
Jeu avec les adresses mémoire <source lang='asm'>
- A boot program to be loaded onto a boot sector (yay !)
- It demonstrates addressing by reserving a byte for a character (X)
- and trying to print it out, by figuring its absolute memory address.
- this tells the compiler where we expect our code to be in memory
mov ah, 0x0e ; loading the teletype bios routine
- First try
mov al, the_secret ; the_secret is a label int 0x10 ; does the interrupt print an X ?
- 2nd try
mov al, [the_secret] ; the [] means we want the content at the offset of ; the_secret; our first try would only have printed the ; the offset itself int 0x10
- 3rd try
mov bx, the_secret ; bx contains the offset of the_secret add bx, 0x7c00 ; the boot sector always has the absolute address 0x7c00 ; ...which is added to the offset so we get absolute addr ; of the secret mov al, [bx] ; try to print that int 0x10 ; does this print an X ?
- 4th attempt
mov al, [0x7c1e] int 0x10
jmp $ ; jump forever
the_secret: db "X"
- Padding, magic number
times 510 -($-$$) db 0 ; fill the rest of the boot sector with zeroes dw 0xaa55 ; end with a magic number </source>
Utilisation de la stack <source lang='asm'>
- A boot program to be loaded onto a boot sector (yay !)
- It demonstrates the use of the stack
- and prints 'CAT' indefinitely
mov ah, 0x0e ; teletype bios routine
catprint: mov bp, 0x8000 ; base of the stack is a little above where BIOS mov sp, bp ; where BIOS puts us, so we don't overwrite ; bp is stack bottom, sp stack top ; the stack moves *downwards* in memory ; so eg. here first push will be under 0x8000
push 'T' ; we start pushing characters push 'A' ; the stack only works in 16 bits wide, remember that push 'C' ; and our ASCII are a byte wide
pop bx ; get the top of the stack and put it into bx mov al, bl ; copy the character at the end of bx to al int 0x10 ; print
pop bx ; again mov al, bl int 0x10
mov al, [0x7ffe] ; just to prove the stack goes downwards, ; get the char at 0x8000 - 0x2 (2bytes...), so ; the top of the stack int 0x10
jmp catprint ; jump forever
- Padding, magic number
times 510 -( $ - $$ ) db 0 ;fill the rest of the boot sector with zeroes dw 0xaa55 ; end with a magic number </source>
Utilisation de conditionnelles
; ; A boot program to be loaded onto a boot sector (yay !) ; It demonstrates the use of the stack ; and prints 'CAT' indefinitely mov ah, 0x0e ; teletype bios routine mov bp, 0x8000 ; base of the stack is a little above where BIOS mov sp, bp ; where BIOS puts us, so we don't overwrite ; bp is stack bottom, sp stack top ; the stack moves *downwards* in memory ; so eg. here first push will be under 0x8000 push ' ' push '!' push 'T' ; we start pushing characters push 'A' ; the stack only works in 16 bits wide, remember that push 'C' ; and our ASCII are a byte wide catloop: pop bx ; get the top of the stack and put it into bx mov al, bl ; copy the character at the end of bx to al int 0x10 ; print cmp bl, ' ' ; is bl a space character ? je theend ; if it is, jump to the end jmp catloop ; otherwise, jump back to print ; don't forget to jump here ! otherwise, you ; keep going theend: jmp $ ; ; Padding, magic number ; times 510 -( $ - $$ ) db 0 ;fill the rest of the boot sector with zeroes dw 0xaa55 ; end with a magic number
Fonctions
Ces deux fichiers vont de pair.
Fonction print (printfunc.asm):
<source lang='asm'>
- A printing function
- Takes a null-terminated string and prints it, basically
- Gets the first CHAR's address in bx and print until we find a null
pusha ; push ALL the registers to stack so we don't ; overwrite what is not ours print_func: mov ah, 0x0e ; ax == 0x0e00 "scrolling teletype" BIOS mov al, [bx] ; mov the first char at address bx into al cmp al, 0x00 ; is it a null ? je end_func ; if it is, stop there int 0x10 ; otherwise, print add bx, 0x1 ; bx now points to next char jmp print_func ; next letter
end_func:
popa ; restore the registries (registers ?)
ret ; return
</source>
main program
<syntaxhighlight lang='asm'>
- A boot program to be loaded onto a boot sector (yay !)
- It prints something using functions !
[org 0x7c00] ; load this code at this address mov bx, HELLO_MSG ; Move (the content of the label HELLO_MSG)'s address to bx call print_func ; call our function
jmp $ ; hang
- Data here !
HELLO_MSG: db 'Welcome to ChatOS', 0x00 ; the 0 is a null
- Here, we include our function
- it simply takes the content of the file and puts it here
%include "printfunc.asm"
- Padding, magic number
times 510 -( $ - $$ ) db 0 ;fill the rest of the boot sector with zeroes dw 0xaa55 ; end with a magic number
</syntaxhighlight>