Assembleur : boot sector

De Justine's wiki
Aller à la navigation Aller à la recherche

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>