Obsah    Kapitoly: 12345678,  |  X.1X.2X.3X.4,  |  Y1 Y2 

2) Trochu věcí okolo

Než budeme moci začít psát vlastní program, musíme si říct pár věcí, bez kterých to asi nepůjde.

2.1) Paměť

Sám bych nevěřil, jak je důležité znát alespoň trochu uspořádání paměti. (Alespoň v programování pro DOS, tedy 16bitové aplikace) Přeskočím věci o maximálním adresovatelném prostoru a různých omezeních v případě reálného módu paměti apod. V dnešní době je to stejně na nic, protože dnes je to o něčem trochu jiném.

Zaměřím se teď na vysvětlení pojmů segment a offset. Kdysi dávno, v době kdy počítače byly tak trochu ještě v plenkách a procesory se označovaly čísly jako 8088, si někdo řekl, že nikdy nebude třeba, aby počítače používali více než 1MB paměti . V té době se to všem jevilo jako dostatečná rezerva, a proto se přistoupilo k následující adresaci paměti:

1MB je, jak jistě víte 220. To znamená, že abyste mohli poukázat na jakékoli místo v této paměti, potřebujete 20bitovou paměť, v tomto případě registr procesoru (viz. kapitola Registry procesoru). Tehdy neměli o 32bitových registrech ani ponětí a 16bitů bylo očividně málo. Složení dvou registrů by dalo 32bitů, tedy adresaci 232 = 4294967296 Byte = 4GB. To bylo na tehdejší dobu zbytečně moc. Proto se vzaly dva registry, které společně tvořili 20bitovou adresu. Nějak takto:

 19  18  17  16  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0 
 | ----- Segmentový registr (CS, DS, ES, FS, GS, SS) ------ |
                  | --------- Offsetový registr (SP, BP, SI, DI) ---------- | 
Segmentový registr je tedy ta část adresy, která je posunuta o 4 bity doleva a offsetový registr upřesňuje ony čtyři bity, které se do segmentové části nevešly.

Absolutní adresu v paměti tedy získáme následovně:
  Segment * 16
       +
    Offset
       = 
20bitová adresa
  0 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 - - - -  

  - - - - 0 1 0 0 1 0 0 0 1 0 0 1 1 0 1 1  
-------------------------------------------
  0 1 0 0 1 0 0 1 1 0 0 0 1 1 1 1 1 0 1 1  
Není to jednoduché? Každých 16 byte v paměti začíná nový segment a offsetová část upřesňuje byte, který máme namysli. Absolutní adresa se tedy rovná Segment * 16 + Offset a udává se ve tvaru SEGMENT:OFFSET. Všimněte si, že na jednu a tutéž absolutní adresu může ukazovat několik různých kombinací Segmentu a Offsetu. Je to samozřejmě způsobeno tím, že se tato čísla překrývají.

A teď pro zajímavost. Jaké maximální číslo můžete pomocí kombinace Segment:Offset můžete dostat? Víte, že segment i offset jsou 16bitová čísla, tedy nejvyšší hodnota obou je 216 neboli 65536. A teď trochu výpočtů:
65535*16 + 65535 = 1114095.


Pokud si vzpomenete 1MB má ale pouze 1048576 byte. Ta trocha paměti, co máte s tímto způsobem adresace navíc se nazývá "HIGH MEMORY". (V DOSovských dobách jste museli mít ovladač HIMEM.sys abyste měli tuto část přístupnou.) To samozřejmě umět nemusíte. Uvádím to pouze abyste o tom prostě věděli.

2.2) Režimy procesoru

To, co jste se dozvěděli o paměti v předcházejících odstavcích není vždy úplně pravda. A pokud se ptáte proč tak abych vám odpověděl vrátíme se trochu zpět do minulosti. Představte si doby, kdy procesory byly procesory ještě malé a moc toho neuměly. Poté přišly nové a konstrukčně lepší. Samozřejmě spousty programů bylo psáno pro ty staré a tak by si nový procesor moc lidí nekoupilo. Proto byly ty novější procesory vybaveny takovou vychytávka, která se nazývá režimy procesoru.

Rozeznáváme 2 režimy procesoru:
  • Real mode. Neboli reálný režim procesoru
  • Protected mode. Neboli chráněný režim procesoru

    Co to znamená? Že lepší procesor, například Pentium, pokud je přepnuto do Real módu se chová, úplně stejně jako například stařičký procesor 8086.
    Pokud ovšem je procesor přepnut do Protected módu, už si můžete vychutnat všechny nové a vylepšené funkce onoho procesoru.

    No a jaký je konkrétní rozdíl mezi těmito módy? Tak začněme ve stručnosti Realným módem:
  • Realný mód procesoru Co je to nejdůležitější, v prvních fázích této učebnice se budeme zabývat právě programováním v reálném módu procesoru. V tomto módu je maximální adresovatelná kapacita programu maximálně 1MB. Používají se pro její adresaci výše zmíněné Segmenty a Offsety.
    Další podrobnosti možná až příště.
  • Chráněný mód procesoru Zde už je správa paměti trochu jiná. Používají se mechanismy, které se nazývají segmentace a stránkování. Dále je možno adresovat až 4GB (232 byte) a pár dalších věcí, které nejsou pro nás momentálně podstatné.

    2.3) Registry

    Registr je jakási rychlá paměť, která je přímo v procesoru a kterou budete hojně využívat. U šestnáctibitových počítačů (286) měly registry velikost 16bitů a od 386ek je velikost registrů 32bitů. S lepšími procesory vzrůstá i počet registrů, ale pro nás jsou důležité pouze tyto.

    2.3.1) Obecné registry - AX, BX, CX, DX

    Tyto registry jsou nejpoužívanější a mají 16bitů. Ve skutečnosti jsou ale 32bitové. Potom je označujeme jako EAX, EBX, ECX, EDX. Názvy registrů prý nejsou takovéto pouze náhodou. (Někdo si asi pohrál a vymyslel čtyři abecedně po sobě jdoucí slova, kterými nazval ony registry.)
  • AX - Accumulator, neboli střádač
  • BX - Base, neboli bázový registr
  • CX - Counter, neboli počítač cyklů
  • DX - Data, neboli datový registr.

    Jak už bylo řečeno, registry jsou 32bitové, pod označením AX, BX, CX, DX je přístupných pouze 16 dolních bitů. Ty ještě rozdělujeme na AH, AL, BH, BL, CH, CL, DH a DL, neboli horních (high ) 8 bitů a dolních (low) 8 bitů. Že je to trochu nesrozumitelné? Tak snad pomůže obrázek.

    Takto je rozdělen registr EAX:
    čísla bitů:  
      31                  15        7         0  
       | --------------- EAX ---------------- |  
                           |------- AX ------ |  
                           |-- AH --||-- AL --|  
    
    AL je tedy spodních 8bitů registru EAX, AH je druhých 8bitů a AX je AH a AL dohromady. Změníme-li tedy hodnotu AX, změníme tím zákonitě i AH a AL.

    Dejme tomu, že zadáme:
            AH:= FFH
            AL := 00H
    Potom hodnotu AX získáme složením AH a AL.
            AX = FF00H

    Dejme tomu, že chci aby:
            AH = 35H
            AL = 09H
    Lze to udělat v jenom řádku a to změnou celého AX:
            AX := 3509H

    2.3.2) Obecné registry - SP, BP, SI, DI

    Platí pro ně to samé jako pro registry AX, BX, CX, DX. Jsou 32bitové (pokud je před nimi ještě E) a SP, BP, SI, DI jsou jejich 16bitové části. Tyto registry se používají pro uložení offsetu (viz výše).
  • SP - obsahuje offset adresy vrcholu zásobníku. (Stack Pointer)
  • BP - určen pro ukládání offsetu při práci se zásobníkem (Base Pointer)
  • SI - určen pro uložení offsetu zdroje (Source Index)
  • DI - určen pro uložení offsetu cíle (Destination Index) U těchto registrů se nedostanete přímo k 8bitové části. (Nemají žádné SL a SH apod.)

    2.3.2) Segmentové registry - CS, DS, ES, FS, GS, SS

    Tyto registry jsou 16bitové. Používají se pro uložení segmentové části.
  • CS - Code Segment. Segment kódu programu. Nelze přímo číst ani do něj zapisovat.
  • DS - Data Segment. Segment dat programu. (U *.com programu platí CS=DS=ES - dá se předělat)
  • ES - Extra segment
  • FS - Volné použití.
  • GS - Volné použití
  • SS - Segment zásobníku. (SS:SP - kompletní adresa na vrchol zásobníku.) Pozor!: Všechny segmentové registry nelze přímo měnit.

    2.3.3) Speciální registry - IP a FLAGS

    Tyto registry jsou každý čímsi zvláštní.
  • IP - Instruction Pointer. Ukazuje offset právě vykonávané instrukce. Přímo nelze měnit, ale oklikou ano. (CS:IP je kompletní adresa právě vykonávané instrukce.)
  • FLAGS - VELMI důležitý registr. Je 32bitový, ale pro naše programování postačí pouze 16bitová část, ostatně jako u všech předešlých registrů. U tohoto registru nás nezajímá přímo hodnota registru, ale hodnota jednotlivých bitů(vlaječek). Ty jsou v něm rozděleny takto (pouze dolních 16bitů):

    čísla bitů:  
      15   14   13-12   11   10   9   8   7   6   5   4   3   2   1   0  
       0   NT    IOPL   OF   DF   IF  TF  SF  ZF  0   AF  0   PF  1   CF
    
    Bity mají následující význam:
  • OF - Overflow Flag. Vlajka přetečení. Nastaví se na 1, je-li výsledek aritmetické operace větší než cílová hodnota
  • DF - Direction Flag. Řídí směr zpracovávání řetězových operací. Při hodnotě 1 se řetězce zpracovávají odpředu. (SI a DI se zvyšuje). Je-li tento příznak (bit, vlaječka, jak chcete) na 0 postupuje se naopak. Nuluje se instrukcí CLD. Nastavuje STD.
  • IF - Interrupt Flag. Je-li 1 je povoleno přerušení (Mimo nemaskovaného přerušení viz dále), jinak je přerušení zakázáno. Nastavuje se instrukcí CLI - nulování. STI - nastavení.
  • TF - Trap Flag. Využívá se při krokování. Je-li tento příznak nastaven volá se po každé instrukci INT 3.
  • SF - Sign Flag. Je to samé jako nejvyšší bit výsledku. Pro záporná čísla platí SF=1.
  • ZF - Zero Flag. Jeli výsledek operace 0, ZF=1.
  • AF - Auxiliary Carry Flag. Pomocná vlajka přenosu. Rozšíření CF. Pokud je 1, došlo k přenosu z dolní poloviny 8 nebo 16bitového čísla.
  • PF - Parity Flag. Hodnota tohoto příznaku je 1 pokud dolních 8 bitů právě provedené operace obsahuje sudý počet "1".
  • CF - Carry flag. Vlajka přenosu. Slouží pro přenos mezi čísly o více slovech.
    Tak to je stručně o registrech prozatím vše.

    2.4) Přerušení

    Přerušení je signál, který procesoru vyšle nějaký hardware nebo program, aby si zabral procesor pro sebe. Krásným příkladem je stisk klávesy na klávesnici. Mikroprocesor musí přerušit svou činnost, aby udělal to, co má stisk klávesy udělat.

    Rozeznáváme tři typy přerušení. Hardwarové, softwarové a nemaskované (NMI - Not Masked Interrupt).
  • Hardwarové přerušení vyvolává nějaké zařízení v počítači. Disk (Int 13H), klávesnice při stisku klávesy (Int 9) apod. V případě, že je IF, neboli vlaječka přerušení nastavena na 1, procesor přeruší svou činnost a zpracuje událost, kvůli které je přerušení voláno.
  • Softwarové přerušení je vyvoláno programem. Programátor si toto přerušení musí napsat do svého programu pomocí instrukce INT. Díky těmto přerušením si programátor v assembleru může vychutnat komfort (poznáte o čem mluvím) funkcí DOSu (přerušení Int 21H) BIOSu (Int 15H) atd.
  • Poslední přerušení se vlastně ani mezi druhy přerušení nezařazuje. Je to jediné přerušení, které nelze zakázat nastavením příznaku (vlaječky) IF na 0. Jedná se totiž o přerušení vyvolané výpadkem proudu, ranou kladivem do procesoru, vyhozením z okna apod.

    Všechny moderní mikroprocesory mají takzvaný vektorový systém přerušení. To znamená, že každé přerušení má své číslo. Na určitém místě v paměti je uložena tabulka vektorů přerušení. Vektor přerušení, který je dán číslem přerušení se "podívá" do té tabulky, ve které je zapsána adresa podprogramu, který má ono přerušení zpracovat. (Výhodou této tabulky je, že si tuto adresu můžete změnit a zpracovávat si takováto přerušení sami.) Pro ilustraci; v praxi to vypadá tak, že N-té přerušení spustí tedy přes N-tý vektor N-tý podprogram, který přerušení zpracuje.

    2.5) Překladač

    Bez něčeho, co nám přeloží náš zdrojový kód do spustitelného programu bychom se asi neobešli. Takže potřebujeme nějaký kompilátor, který bude vytvářet *.com soubory. Osobně doporučuji TASM a TLINK. Najdete je klasicky s Turbo Pascalem nebo Borland C. Též si je můžete stáhnou na mých stránkách, nebo kdekoli jinde.
    Pro správnou kompilaci (do *.com) je nutné zadat do příkazové řádky následující příkazy:

            TASM Název_Vašeho_Souboru.asm /z
            TLINK Název_Vašeho_Souboru.obj /t /x

    Pokud chcete do (*.exe) Stačí pustit Tasm a Tlink a ty vám již vypíšou podrobnější nápovědu.

    Jinak assembler můžete psát v poznámkovém bloku, protože žádné prostředí ve kterém by se dal programovat neexistuje. Soubor nazvěte třeba "Hello.asm". Napište kód, který chcete. Soubor uložte. Do příkazové řádky zadejte výše uvedené parametry a měli byste mít spustitelný soubor na světě.

    Pro ulehčení doporučuji si vytvořit dávkový soubor, nebo si stáhněte ASMEditor.


    Předchozí kapitola Nahoru Následující kapitola