8080 – algoritmy 1

Algoritmy! Neseme čerstvé algoritmy! Berte, paní, jsou zadarmo a přitom tak užitečné!

Přesun bloku dat

Máme 32 bajtů na nějaké adrese a chceme je zkopírovat na adresu úplně jinou. Jak na to? Jednoduše – použijeme instrukci LDIR a… cože? Ajo vlastně, instrukci LDIR má až procesor Z80, u 8080 nic takového není, tam si to musíme pořešit jináč. Třeba takhle:

Nejprve si naplním registry patřičnými údaji – do registrů HL dám adresu, kde se blok dat nachází, do registrů DE adresu, kam chci blok přesunout, do registrů BC počet bajtů, které chci přesunout. Ve smyčce LDIR (která se víceméně chová shodně s instrukcí LDIR procesoru Z80, až na to, že tady je pomalejší a přepisuje obsah registru A) se děje následující: Do registru A vezmu bajt z adresy HL, uložím ho na adresu DE, obě adresy zvýším o 1, od počítadla BC odečtu jedničku, a když je BC nenulové, opakuju smyčku.

Bohužel (tedy někdy spíš bohudík) instrukce INX, DCX nemění stav příznaků. Což je dobře, jak uvidíme v dalších algoritmech, ale v případě, jako je tento, by se nám hodilo, kdyby DCX dokázala nastavit příznak Z, jako že je výsledek nula. Ale nedělá to, takže si to musíme vyřešit jinak (zvykejte si, to je assembler!)

Každý podobný případ lze řešit několika způsoby, ale časem se ustálí vždy jeden návrhový vzor, který má nejméně nevýhod. V případě „zkontroluj, jestli je ve dvojici registrů 0“ se používá ten, který jsem ukázal v kódu: do A si zkopíruju jeden registr z dvojice, udělám OR s druhým (vzpomeňte – výsledkem OR je nula, pokud všechny bity obou operandů jsou nulové) – a protože OR už příznakový bit Z změní podle výsledku, tak jsme získali, co jsme chtěli.

Jak bychom to ale řešili, kdyby v A bylo něco, co chceme zachovat? Řešit by to samosebou šlo, jen – jinak a náročněji.

Přepsání bloku dat

V procesoru Z80 se instrukce LDIR používá i k jiné operaci, než je přesun bloků dat – totiž k mazání (přesněji k nastavení celého bloku na konkrétní hodnotu). Využívá se toho, že nastavíme registry HL a DE určitým způsobem – HL na začátek bloku, který se má smazat, DE na adresu o 1 vyšší. Ručně pak nastavíme první bajt bloku (ten, kam ukazuje HL) na požadovanou hodnotu a LDIR postupně první bajt bloku nakopíruje na další a další adresy. BC je v takovém případě (délka bloku – 1). Pokud nastavíme DE na adresu větší než HL+1, třeba HL+4, vyplní LDIR blok paměti vzorkem dat (HL, HL+1, HL+2, HL+3).

Fungovalo by to i s tím naším LDIRem? Ale určitě fungovalo, jen je to v případě nastavení nějaké oblasti v paměti na konkrétní hodnotu trošku kanón na vrabce (a to v assembleru znamená vždy: stojí to paměť a čas). Jednodušší postup je zde:


Všimněte si, že hodnota, která se do bloku paměti zapisuje, není v registru A, ale v registru E. Je to právě kvůli výše popsanému postupu na testování BC na nulu – využívá registr A. Kdybychom v něm měli tu hodnotu, přepsali bychom si ji. Abychom si ji nepřepsali, museli bychom si ji někam uložit (pravděpodobně třeba do toho registru E), pak zase načíst zpátky… Výsledek by byl sice funkční, ale pomalejší a delší. A to jen kvůli tomu, že chceme číslo v jiném registru?! Kdepak.

Dělení

Tuhle jsme si ukazovali, jak násobit dvě celá čísla bez znaménka. Dělení můžeme napsat analogicky – buď jako postupné odčítání, nebo pomocí rotací a odčítání. Ten druhý postup opět můžeme napsat bez triků, nebo s trikem…

Tady je postup pro dělení dvojregistru HL registrem D. Matematicky: HL = HL / D, zbytek po dělení je v registru A. Je to postup s trikem (používá se „trojitý registr“ AHL, do A se postupně nasouvají bity z HL a kontroluje se, jestli už je mezistav větší než dělitel).


Ukázali jsme si pár triků a předvedli pár algoritmů. Ovšem v programování obecně a pro assembler zvlášť platí, že:

1. Není důležité si tyhle algoritmy pamatovat, důležitější je umět je napsat, když je potřeba

2. Je dobré si tyhle algoritmy pamatovat, aby je člověk nepsal zbytečně znovu

3. Nejdůležitější je dokázat se rozhodnout, jestli pro daný konkrétní případ platí 1 nebo 2!

Líbil se vám článek? Podpořte autora na Patreonu
Příspěvek byl publikován v rubrice 8080. Můžete si uložit jeho odkaz mezi své oblíbené záložky.

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *