Jednoduchý operačný systém v assembleri

Kým som o assembleri nič nevedel tak sa mi zdalo že je to niečo strášne zložité a nepochopiteľné. Ale zistil som že je to omnoho jednoduchšie než som si myslel. Na robenie operačného systému potrebujete vedieť trošku robiť v assembleri tak som sa snažil všetko prehľadne a názorne vysvetliť aby to pochopil každý. Ale mali by ste mať aspoň trochu znalostí z programovania aby sa vám mohli začať robiť nejaké súvislosti. Proste nie je to dobrý nápad učiť sa programovať cez assembler.

Klaykap


Ako funguje procesor alebo skôr assembler

Assembler je vlastne jazyk v ktorom píšeme príkazy ktoré sú tými úplne najzákladnejšími vecami čo vie procesor robiť. Takže sa ako prvé musíme podučiť čo to o procesori. Každý procesor má v sebe takú malinkú pamäť. Jednotlivé časti pamäte sa nazývajú registre. Je ich dosť veľa, ale pre nás sú dôležité iba tieto:

AX, BX, CX, DX Tieto registre môžeme voľne využiť na čokoľvek
SP Register zásobníka(o chvíľu vysvetlím)
IP Register ktorý má uložené ktorý príkaz sa vykonáva

Tieto registre sú 16 bitové čiže v nich môžu byť čísla od 0 až do 65536 ale existujú aj registre 8 bitové a to AH, AL, BH, BL, CH, CL, DH, DL ktoré využívajú rovnakú časť pamäte tak že na časti pamäti pre register AX je polovica register AH a druhá polovica AL a rovnako je to aj s BX, CX a DX. Existuje samozrejme aj množstvo iných registrov ktoré tu na začiatku nespomínam ako napríklad SI, DI, SS, DS atď tak sa tím nedajte zmiatnuť ak ich niekde uvidíte. Do akéhokoľvek registra vkladáme číslo príkazom mov. Keď chceme dať do AX číslo 10, napíšeme

    mov ax,10
    

Pomocou príkazu mov môžeme zapisovať aj do RAM pamäti a to tak že keď chceme zapísať na 500tý bajt RAM pamäte číslo 100, treba napísať

    mov ax, 500
    mov [ax],100
    

Samozrejme namiesto ax tam môže byť aj register bx, cx alebo dx. Ale teraz ku kódu. Znaky [] znamenajú že číslo čo je v nich označuje na ktorý bajt v RAM pamäti sa má zapísať druhé číslo. V našom prípade je v registri ax 500 takže sa bude číslo 100 zapisovať na 500stý bajt. Do pamäti nemusíme zapisovať len príkazom mov ale aj príkazmi db, dw a dd ktoré zapisujú číslo na miesto seba. Db zapíše bajt(8 bitov), dw slovo(16 bitov) a dd dvojité slovo(32 bitov).

Register sp označuje miesto zásobníka v RAM pamäti. Zásobník je že keď si potrebujeme nejaké číslo nachvíľu odložiť do pamäte, môžeme to spraviť príkazom push nejakéČíslo. Procesor sa pozrie do registra sp a nejakéČíslo zapíše na to miesto RAM pamäte aké je v sp. Jednoducho ako keby spravil príkaz mov [sp], nejakéČíslo. Ale keď to číslo zapíše, zmenší hodnotu v sp o jedno. Vybrať si číslo zo zásobníku robíme príkazom pop nejakýRegister. To spraví že procesor vykoná ako keby príkaz mov nejakýRegister, [sp] a zvýši hodnotu sp o jedno. Preto sa sp nastavuje na koniec pamäti. Síce nechápem prečo to tí čo vymysleli zásobník spravili takto ale je to tak a preto sa sp nastavuje na koniec pamäte aby sa mali kam čísla v ňom ukladať.

S registrom ip my nebudeme pracovať ale je dobre vedieť ako funguje. Procesor pracuje tak že sa pozrie aké číslo je v ip, potom z tej časti pamäte vykoná príkaz a zvýši hodnotu ip o jedno. Register ip je teda zodpovedný za to že procesor čokoľvek robí. PRETO REGISTER IP NENASTAVUJEME!

Nuž, teraz už viete ako to funguje s počítačom, teraz sa ešte musíte podučiť najčastejším príkazom v assembleri:

mov Vkladá čísla do registrov alebo pamäti.
call Tento príkaz volá metódu ktorá je za ním napísaná. Procesor začne vykonávať metódu až kým nenájde príkaz ret.
ret Koniec metódy a procesor začne znovu vykonávať príkazy za miestom skadiaľ bola metódy vyvolaná príkazom call.
jmp Procesor bude vykonávať príkazy odtadiaľ kam mu tento príkaz povedal.
cmp Porovnáva dve čísla.
int Volá programy BIOSu.

S tými programami BIOSu je to tak, že tí čo robili BIOS boli takí milí že doňho spravili pár programíkov na písanie na obrazovku, čítanie z disku atď... Tieto programy žiaľ môžeme využívať len v reálnom móde ale na začiatok sú dobré že sa nimi rýchlo dobracujete ku hmatataľnému výsledku. Teraz už toho vieme dosť a môžeme napísať svoj prvý operačný systém v assembleri. Vytovorte si niekde súbor os.asm a skopírujte doňho tento kód:

bits 16

start:  ; tato metoda musi byt definovana a nou sa zacina nas kod
    mov ax, 07C0h		; najprv nastavime velkost pouzitelnej pamate
    add ax, 288		    ; (ax(4096) + 512) zvacsujeme ax o velkost pamate ktoru pouzijeme
    mov ss, ax          ; teraz sme nastavili velkost pamate ktoru pouzijeme
    mov sp, 4096        ; a zasobnik

    mov ax, 07C0h		; nas bootloader je nahrany na cislo 0x07C0
    mov ds, ax          ; cize zaciatok pamate ktoru pouzivame dame do ds


    mov si, text    ; v registre si je odkaz na text
    call napisat	; metoda pre pisanie na obrazovku

    jmp $

    text db 'Hura! Nieco som napisal na obrazovku!', 0


napisat:			; definicia metody
    mov ah, 0Eh		; program BIOSu 0x0E je pre napisanie znaku na obrazovku 

.opakovat:
    lodsb			; nahranie do al cislo na ktore ukazuje
    cmp al, 0       ; porovname ci je v al 0
    je .hotovo		; ak ako, program skoci na .hotovo
    int 10h			; inak zavola program BIOSu ktory na obrazovku napise znak
    jmp .opakovat   ; a znovu skocime na .opakovat

.hotovo:
    ret


    times 510-($-$$) db 0
    dw 0xAA55
    

Takže tuto názorne vidíte ako sa programuje s príkazmi a aj som sa to snažil príhodne v kóde okomentovať. Jediné čo treba vysvetliť sú posledné dva riadky. Iste si spomínate že v návode Ako začať som napísal že po štarte počítača BIOS načíta z hardvéru prvých 512 bytov. Tito by mali načítať jadro operačného systému a preto sa volajú bootloader. Ale keďže tento "operačný systém" je véééľmi jednoduchý, stačí ho mať v bootloaderi. Ale na to aby BIOS bootloader nahral musí sa končiť práve na tieto dva riadky.

Spúšťanie systému

Teraz si otvorte priečinok so súborom os.asm v termináli(pravé tlačidlo>otvoriť v termináli) a napíšte:

    nasm -f bin -o os.bin os.asm
    

Program nasm si prečíta náš súbor a vytvorí z neho súbor s číslami ktorým počítač rozumie. Tomuto sa v programátorskom svete hovorí kompilácia. Náš skompilovaný systém si teraz spustíme cez emulátor Qemu:

    qemu-system-i386 os.bin
    

Ak ste sa zdárne dostali až sem tak gratulujem, máte odo mňa potvrdenie že ste sa naučili programovať v assembleri! Ďaľším príkazom sa už teraz podučíte veľmi rýchlo.

os development vytvoril Klaykap
www.000webhost.com