.-=[ HIGH / low ]=-.
Ohlasy na moje příspěvky do rubriky programování jsou různé,
někdo píše: "Dík, právě tohle jsem potřeboval !", ale jsou i ohlasy
typu: "No jo, to je všecho pěkný, ale co to tam má bejt za změť
třípísmenkovejch blbostí a vůbec tohle mi je nanic, když nevim jak to
vlastně funguje..." Přívaly dotazů ohledně minulého článku na
scrolling v textovém režimu mě utvrdil v tom, že bude asi lepší, když
začnu od píky a vysvětlím význam těch "třípísmenkovitejch blbostí",
aby už podobné problémy nenastaly. V procedůrce SetTextLine byl jeden
velice záludný překlep. Místo mov ax,ch mělo být mov ax,0ch. Ten, kdo
alespoň trochu programuje v assembleru ví, že k podobným smrťákům
dochází dosti často. Je to problém s zápisem hexadecimálních čísel.
Jejichž přítomnost se udává překladači pomocí písmenka "h" na konci
hexadecimálního zápisu, ale aby bylo při překládání poznat, zda se
jedná o jméno proměné nebo o hexadecimální číslo, je nutné psát vždy
před hexadecimální číslo začínající nějakým znakem z abecedy nulu.
Většinou se nic nestane a překladač ohlásí error, ale v tomto případě
se nám do toho zapletlo ještě značení pro horní bajt registru cx, což
se při překladu nepozná a vesle se při vykonávání instrukce přiřazuje
do ax hodnota z registru ch místo konstanty 12. Většina lidí, kteří
mi psali, že jim scrolling nechodí na tuto chybu nepřišla, z čehož se
dá usoudit, že si buď nedali práci jí odhalit a nebo jim assembler
nic neříká. Je více než jasné,že většina začínajících programátorů se
učí nejprve nějaký high-level jazyk a časem přestupují na assembler.
O tom, jestli je toto zrovna vhodný způsob, jak se naučit efektivně
programovat, by se dalo polemizovat. Z hlediska pochopení
problemiatiky programování je bezpochyby lepší, když se začíná
s názorným a přehledným high-level jazykem. Jenže většina takto
poznamenaných jedinců má problémy s přechodem na assembler. Podle
mého názoru nemá smysl programovat 100% v assembleru, jako je zvykem
u některých demo-skupin, které zakládaájí spolky typu 100% asssembler
rulez atp. Programátoři sami přiznávají, že programují v čistém
assmbleru, ale hojně používají maker. Nějaký high-level jazyk je
v podstatě makrojazyk assembleru. Ať je to Pascal nebo C++, pokaždé
se jedná o určitou filozofii zjednodušení programátorovi práci při
vytváření složitých programů. Kdyby si všechno musel psát
v assembleru, asi by se po čase zbláznil z nesčetného možství
instrukcí a změti proměnných. A vůbec ani nechci mulvit o problémech
s odlaďováním, které jsou v high-level jazycích ve srovnání
s klasickým assembleroidním debugerem procházka růžovým sadem. Ale na
druhou stranu jsou tu určité problémy týkající se generování
výsledného kódu high-level jazyků, které zpočívají v neschopnosti
algoritmizovat některé fígle, jimiž se výrazně urychluje výsledný
kód. Většina low-level operací se proto musí psát přímo v assembleru
a záleží na překladači jakým interfacem pro návaznost high/low-level
jazyků disponuje. S bombastickým vývojem stále dokonalejších
a rychlejších procesorů a vůbec všech komponent PC začínají
programátoři lenivět a oddávají se objektovjě-vizuálním choutkám.
Borlandovské Delphy jsou v podstatě dobrý nápad realizovaný na
nechutně mizerném základu Woken. Pokud by se něco takového
realizovalo na základě naprogramovaných knihoven, které vytvořili
opravdoví profesionálové a ne banda vychytralých příživníků, dalo by
se o projektu Delphy uvažovat v kladném symslu, ale za takovéto
situace je jeho využívaní více méně sebevraždou. V současné době je
proto kombinace low/higih-level jazyků tím nejprogresivnějším
řešením.
.-= Turbo Assembler =-.
Udělat něco jako učebnici assembleru, ve které by byly jen
příklady a žádná teorie, by nemělo v podstatě žádný smysl. Já jsem
vybral menší kompromis. Beru na vědomí vaše názory na papírové
publikace o assembleru, ale bez základních poznatků to opravdu nejde.
Ale nebojte se, teorie a příklady budou půl na půl, což je myslím
docela zajímavý poměr, alespoň jsem se s něčím podobným v minulosti
nesetkal. Kdo umí programovat v Pascalu nebo v Céčku a když se podívá
na assembler dělá se mu mdlo, si musí uvědomit jednu podstatou věc.
High-level jazyk zajišťuje programátorovi stovky různých funkcí,
které vytvářejí jakýsi neprůhledný obal pod kterým se skrývají
instrukce, které tyto funkce vykonávají. Programátor se tedy může
věnovat svým konkrétním problémům s tím, že se už nemusí starat o to,
jak vlastně funguje adresování paměti nebo práce s vstupem
a výstupem. Programovací jazyk mu všechny tyto "neviditelné" operace
obstará sám. Pokud chce programovat v assembleru, musí se s chtě
nechtě seznámit se vším, co se vlastně v počítači děje. Začneme tedy
pěkně popořádku. Na samém počátku je paměťové místo v procesoru:
registr IP, který obsahuje offset adresy právě prováděné instrukce.
Tato instrukce se nachází někde v operační paměti. Její umístění je
určeno adresou CS:IP, kde CS je segment ve kterém jsou uloženy
instrukce spuštěného programu, spolu s registrem IP určuje tedy místo
v paměti, kde se nachází zpracovávaná instrukce. Adresování paměti
stylem segment:offset se provádí následovně: jeden segment má
velikost 64KB (65536 bajtů), procesor jeho umístění určuje pomocí 16
bitů (2 bajty). Offset je relativní ke svému segmentu a je určen také
16 bity. Výslednou lineární adresu získáme tak, že segment vynásobíme
16 a přičteme hodnotu offsetu. Procesor (v tomto případě i8086) je
pak schopen mapovat 20-bitovou fyzickou adresou až 1MB. Spuštěný
program má obvykle část paměti vyhrazenou pro instrukce (registr CS
- code segment), část pro data (registr DS - data segment) a část pro
zásobník (registr SS - stack segment). Do datovém segmentu si
programátor naskládá statické proměnné nebo konstanty, které bude při
práci potřebovat. Zásobník slouží pro dočasné odkládání registrů
například při volání podprogramu nebo kdykoli, kdy je to potřeba.
Systém ukládání se jmenuje LIFO (Last In First Out). Pokud ukládáte
do zásobníku například nějaký registr, zapíše se jeho hodnota na
adresu SS:SP a SP (registr SP - stack pointer) zmenší o délku
ukládaného registru. Při opačném procesu se registr SP zvětší
o velikost registru do kterého hodnotu ukládáme a naplní ho hodnotou
z adresy SS:SP. Procesory i8086 mají celkem 14 16-bitových registrů:
AX, BX, CX, DX, CS, DS ,SS, ES, SP, BP, SI, DI, IP a stavový registr.
Ten je rozdělen na 9 bitových flagů, které se značí: OF (Overflow
Flag), DF (Direction Flag), IF (Interupt enable Flag), TF (Trap
Flag), SF (Sign Flag), ZF (Zero Flag), AF (Auxilary Flag), PF (Pariy
Flag) a konečně CF (Carry Flag). Jejich funkci si vysvětlíme při
konkrétních případech. Tak a teď dost teorie a vrhnem se rovnou na
věc. Aby jste měli co studovat, připravil jsem pro vás dva prográmky.
Ten první je zobrazovač formátu CEL (Autodesk Animator) pro velikost
obrázku 320x200 v rozlišení 320x200x256. A druhý je už funkční
scrolling v textovém režimu. U každé instrukce je popis, co se při
jejím vykonávání bude dít. Na konec mého prvního povídání
o programování v assembleru ještě zařazuji seznam instrukcí, které
v prográmcích používám a jejich stručný popis. Tady to je.
ReDox
P.S.: Pokud si budete chtít příklady vyzkoušet, při práci budete
potřebovat kompilátor Turbo Assembleru a Linker. Dodávají
se s Borland Pascalem 7.0, taže by jejich schánění nemělo
dělat veliké potíže.
výheň