str.53 Odečítací povely ---------------- ----------------------------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | Analog BASIC | |---------------------------------------------------------------| | 8mi bitové odečítací | |---------------------------------------------------------------| | SUB A | A=A-A | SZHV1C| 97 | A=A-A | | SUB B | A=A-B | SZHV1C| 90 | A=A-B | | SUB C | A=A-C | SZHV1C| 91 | A=A-C | | SUB D | A=A-D | SZHV1C| 92 | A=A-D | | SUB E | A=A-E | SZHV1C| 93 | A=A-E | | SUB H | A=A-H | SZHV1C| 94 | A=A-H | | SUB L | A=A-L | SZHV1C| 95 | A=A-L | | SUB (HL) | A=A=(HL) | SZHV1C| 96 | A=A-PEEK (HL) | | SUB n | A=A-n | SZHV1C| D6,n | A=A-n | | | | | | | | SBC A,A | A=A-A-C | SZHV1C| 9F | A=A-A-C | | SBC A,B | A=A-B-C | SZHV1C| 98 | A=A-B-C | | SBC A,C | A=A-C-C | SZHV1C| 99 | A=A-C-C | | SBC A,D | A=A-D-C | SZHV1C| 9A | A=A-D-C | | SBC A,E | A=A-E-C | SZHV1C| 9B | A=A-E-C | | SBC A,H | A=A-H-C | SZHV1C| 9C | A=A-H-C | | SBC A,L | A=A-L-C | SZHV1C| 9D | A=A-L-C | | SBC A,(HL)| A=A-(HL)-C | SZHV1C| 9E | A=A-PEEK (HL)-C | | SBC A,n | A=A-n-C | SZHV1C| DE,n | A=A-n-C | |---------------------------------------------------------------| | 16ti bitové odečítání | |---------------------------------------------------------------| | SBC HL,BC | HL=HL-BC-C | SZHV1C| ED,42 | HL=HL-BC-C | | SBC HL,DE | HL=HL-DE-C | SZHV1C| ED,52 | HL=HL-DE-C | | SBC HL,HL | HL=HL-HL-C | SZHV1C| ED,62 | HL=HL-HL-C | | SBC HL,SP | HL=HL-SP-C | SZHV1C| ED,72 | HL=HL-SP-C | ----------------------------------------------------------------- Tyto povely se chovají analogicky jako u součtu. Povel SUB (Subtract, česky odečti) odečítá bez zohlednění Carry flagu povel SBC (Subtract with Carry, česky odečti s přenosem) zohledňuje Carry flag. Pro 16ti bitové odečítací povely neexistuje žádný povel SUB. Chceme-li tedy od HL reg. odečíst reg. BC, musí se napřed pomocí AND A nastavit zpět Carry flag. Příklad: adresa kód povel Analog BASIC 8000: A7 AND A 8000:C=0 8001: ED 42 SBC HL,BC 8001:HL=HL-HL-C 8003: C9 RET 8003:RETURN Taky při odečítání negativních čísel ve dvojkovém vyjádření se automaticky zohledňuje správné znaménko. Vyzkoušejte si to: str.54 32 bitové odečítání ------------------- A když budete psát program pro odečítání 32 bitových čísel, potřebujete pouze ve shora uvedeném příkladu pro sečítání nahradit povel ADC příslušným povelem SBC a už je věc v chodu. Odečítání 8mi místných decimálních čísel ---------------------------------------- Program na sčítání dvou 8mi místných čísel BCD lze pozměnit na program odečítací. Nahraďte jednoduše povel ADC povelem SBC. Povely Inkrementní (přirůstkové) a Dekrementní (úbytkové) --------------------------------------------------------- Tyto povely pomalu znáte. Povyšují resp. snižují obsah reg. o 1. ----------------------------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | Analog BASIC | |---------------------------------------------------------------| | 8-bit Inkrement | |---------------------------------------------------------------| | INC A | A=A+1 | SZHV0-| 3C | A=A+1 | | INC B | B=B+1 | SZHV0-| 04 | B=B+1 | | INC C | C=C+1 | SZHV0-| 0C | C=C+1 | | INC D | D=D+1 | SZHV0-| 14 | D=D+1 | | INC E | E=E+1 | SZHV0-| 1C | E=E+1 | | INC H | H=H+1 | SZHV0-| 24 | H=H+1 | | INC L | L=L+1 | SZHV0-| 2C | L=L+1 | | INC (HL) | (HL)=(HL)+1 | SZHV0-| 34 |POKEHL,PEEK(HL)+1| |---------------------------------------------------------------| | 16-bit Inkrement | |---------------------------------------------------------------| | INC BC | BC=BC+1 | ----- | 03 | BC=BC+1 | | INC DE | DE=DE+1 | ----- | 13 | DE=DE+1 | | INC HL | HL=HL+1 | ----- | 23 | HL=HL+1 | | INC SP | SP=SP+1 | ----- | 33 | SP=SP+1 | |---------------------------------------------------------------| | 8-bit Dekrement | |---------------------------------------------------------------| | DEC A | A=A-1 | SZHV1-| 3D | A=A-1 | | DEC B | B=B-1 | SZHV1-| 05 | B=B-1 | | DEC C | C=C-1 | SZHV1-| 0D | C=C-1 | | DEC D | D=D-1 | SZHV1-| 15 | D=D-1 | | DEC E | E=E-1 | SZHV1-| 1D | E=E-1 | | DEC H | H=H-1 | SZHV1-| 25 | H=H-1 | | DEC L | L=L-1 | SZHV1-| 2D | L=L-1 | | DEC (H+L) | (HL)=(HL)-1 | SZHV1-| 35 |POKEHL,PEEK(HL)-1| |---------------------------------------------------------------| | 16-bit Dekrement | |---------------------------------------------------------------| | DEC BC | BC=BC-1 | ----- | 0B | BC=BC-1 | | DEC DE | DE=DE-1 | ----- | 1B | DE=DE-1 | | DEC HL | HL=HL-1 | ----- | 2B | HL=HL-1 | | DEC SP | SP=SP-1 | ----- | 3B | SP=SP-1 | ----------------------------------------------------------------- str.55 Jak vidíte jsou dva druhy povelů INC/DEC, takové které povyšují/ snižují 8mi bitové reg. (A, B, C...) a takové které povyšují/ snižují 16ti bitové registry. 16ti bitové povely ovlivňují celý 16ti bitový reg., přenos z L- na H- Byte se provádí vnitřně, automaticky. T.j. stojí-li při povelu INC BC v reg. BC 31FF, nalézá se v něm potom 3200. Protože tyto registry jsou používány nejčastěji jako pointer a obsahují adresy paměťových buňek, se kterými se pracuje průběžně, je velmi užitečné, že 16ti bitové operace INC a DEC neovlivňují flagy, neboť ony mají obsahovat informace o výsledcích provedených operací ale ne o pointerregistrech. Jak jste poznali lze lecos provést pomocí aritmetických povelů. Když pro sčítání a odečítání vícemístných čísel již potřebujeme malé programy, jsou tyto operace přesto prováděny rychle. Pomocí strojového jazyka můžete stanovit s kolika místy chcete pracovat. To je velice užitečné, protože s tím můžete současně určovat sami prostor v paměti pro hodnoty čísel a rychlost počítání. 5.4 Logické povely ------------------ Logickými povely můžete obsazovat určité bity, vymazávat nebo je vyfiltrovávat z jednoho bytu. Současně je těmito povely možné provádět komplikované rozhodnutí. Účinek logických operací AND, OR, XOR najdete popsané v odstavci 1.6. Povely AND ---------- ----------------------------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | Analog BASIC | |---------------------------------------------------------------| | AND A | A=A AND A | SZ1P00| A7 | A=A AND A | | AND B | A=A AND B | SZ1P00| A0 | A=A AND B | | AND C | A=A AND C | SZ1P00| A1 | A=A AND C | | AND D | A=A AND D | SZ1P00| A2 | A=A AND D | | AND E | A=A AND E | SZ1P00| A3 | A=A AND E | | AND H | A=A AND H | SZ1P00| A4 | A=A AND H | | AND L | A=A AND L | SZ1P00| A5 | A=A AND L | | AND (HL) | A=A AND (HL) | SZ1P00| A6 | A=A AND PEEK(HL)| | AND n | A=A AND n | SZ1P00| E6,n | A=A AND n | ----------------------------------------------------------------- Povely AND (And, česky -a- operace) jsou zvlášť důležité, když chceme cílevědomě vymazat určité bity. Nepříznivé na všech logických povelech je, že nelze paměťové buňky přímo adresovat. Jde to jen nepřímo přes registr HL, nebo se předem nabere obsah paměťové buňky do akumulátoru. Všechny logické operace nastavují Carry flag. Proto rádi použijeme AND A nebo OR A, abychom nahradili chybějící instrukci "reset Carry". Obsah A přitom zůstává nezměněn Jako vedlejší efekt se ovšem změní též ostatní flagy. Chcete-li pouze vymazat třetí bit (B2 při obvyklém způsobu počítání B0 až B7) v akumulátoru, aniž by se zbývajíci bity změnily, použijete následující povel : str.56 Příklad: AND FB Působení tohoto povelu se nejlépe vysvětlí ve dvojkové podobě. FB je dvojkově 11111011. Provádí-li se operace AND, všechny bity, které byly násobeny "1", si ponechají své hodnoty. Naproti tomu všechny bity, které se násobí "0" dostanou hodnotu 0. Totéž platí, když se ve vlastních programech šetří prostorem paměti a výsledky se ukládají jako jednoduchá rozhodnutí ano/ne do jednotlivých bitů. Např. bit 0 = prší/ neprší bit 1 = je den/ je noc. Tímto způsobem lze v jednom bytu uložit 8 takových rozhodnutí. Obráceně lze použít operace AND též, aby se z jednoho bytu vyfiltrovaly pouze bity, které potřebujeme pro další operace. Konverze ASCII na hodnotu BCD ----------------------------- Typickým příkladem proto je konverze znaku ASCII na cifru v příslušné číselné hodnotě v systému BCD. V kódu ASCII mají cifry 0...9 kódovanou hodnotu hexa 30...39. Patrně při tom působí rušivě bity vpředu. Příklad: adresa kód povel Analog BASIC 8000: E6 0F AND 0F 8000: A=A AND 0F 8002: C9 RET 8002: RETURN Chcete-li si tyto příklady vyzkoušet můžete před stertem programu předeslat do akumulátoru cifru ASCII, např. A=36. Po provedení programu najdete v akumulátoru hodnotu 06. Tyto povely se dají použít i pro složená rozhodnutí. Ukládají se výstupy jednotlivých rozhodnutí v jednotlivých buňkách (FF=ano 00=ne). Nakonec se provádějí AND operace mezi uloženými hodnotami a povelem JR Z nebo JR NZ v závislosti na výsledku nastane skok. Tímto způsobem pracuje BASIC, jestliže má v podmínkách IF nějakou AND vazbu. Povely OR --------- ----------------------------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | Analog BASIC | |---------------------------------------------------------------| | OR A | A=A OR A | SZ0P00| B7 | A=A OR A | | OR B | A=A OR B | SZ0P00| B0 | A=A OR B | | OR C | A=A OR C | SZ0P00| B1 | A=A OR C | | OR D | A=A OR D | SZ0P00| B2 | A=A OR C | | OR E | A=A OR E | SZ0P00| B3 | A=A OR E | | OR H | A=A OR H | SZ0P00| B4 | A=A OR H | | OR L | A=A OR L | SZ0P00| B5 | A=A OR L | | OR (HL) | A=A OR (HL) | SZ0P00| B6 | A=A OR PEEK (HL)| | OR n | A=A OR n | SZ0P00| F6,n | A=A OR n | ----------------------------------------------------------------- Zatímco pomocí povelů AND můžete určité bity v jednom bytu nastavovat na 0 aniž by byl ovlivňován zbytek obsahu bytu, můžete pomocí povelů OR určité bity nastavovat na 0. Příklad: OR 04 Posazuje třetí bit (B2) z A na 1, protože 4 je dvojkově 00000100. str.57 Konverze cifry BCD na cifru ASCII --------------------------------- K tomu se musí bity B4 a B5 nastavit na 1, aby např. z 05 vznikla kódová hodnota 35. Příklad: adresa kód povel Analog BASIC 8000: F6 30 OR 30 8000: A=A OR 30 8002: C9 RET 8002: RETURN Povely OR (nebo) se dají samozřejmě rovněž použít,aby se daly řešit komplikované složené rozhodování. Přitom lze míchat vazby AND a vazby OR. Exkluzívní povely XOR --------------------- ----------------------------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | Analog BASIC | |---------------------------------------------------------------| | XOR A | A=A XOR A | SZ0P00| AF | A=A XOR A | | XOR B | A=A XOR B | SZ0P00| A8 | A=A XOR B | | XOR C | A=A XOR C | SZ0P00| A9 | A=A XOR C | | XOR D | A=A XOR D | SZ0P00| AA | A=A XOR C | | XOR E | A=A XOR E | SZ0P00| AB | A=A XOR E | | XOR H | A=A XOR H | SZ0P00| AC | A=A XOR H | | XOR L | A=A XOR L | SZ0P00| AD | A=A XOR L | | XOR (HL) | A=A XOR (HL) | SZ0P00| AE | A=A XOR PEEK(HL)| | XOR n | A=A XOR n | SZ0P00| EE,n | A=A XOR n | ----------------------------------------------------------------- Těmito povely se provádí logická exkluzívní operace XOR (výlučné nebo). Mnemonic "XOR" značí "Exclusive OR". Povel XOR se dá použítk cílevědomému invertování obsahu bitu, aniž by se ovlivnil zbytek bitů. Přitom se využívá, že 0 XOR 1 dává 1 a 1 XOR 1 dává 0. Exkluzívní vazba nebo s 1 tedy udělá z jedničky nulu a obráceně. Příklad: XOR 04 Převrací tedy právě třetí bit (B2) akumulátoru, protože 4 je dvojkově 00000100. Kdybychom chtěli invertovat celý byte, jako by se to stalo při logické operaci NOT, pak provedeme prostě XOR FF. Toto lze pak zase použít ve složených rozhodováních. 16bitová změna znaménka ----------------------- U dvojkových čísel s předznamenáním (viz dodatek A3) je někdy potřeba změnit znaménko a udělat z negativního čísla pozitivní nebo naopak. Často používaná metoda pro tuto operaci převrací napřed dvojkovou hodnotu (NOT operace) a následně povyšuje. V následujícím programu se u předznamenaného 16bitového čísla v HL reg. má změnit znaménko. str.58 Příklad: adresa kód povel komentář 8000: 7D LD A,L L=NOT L 8001: EE FF XOR 0FF 8003: 6F LD L,A 8004: 7C LD A,H H=NOT H 8005: EE FF XOR 0FF 8007: 67 LD H,A 8008: 23 INC HL HL=HL+1 8009: C9 RET Vyzkoušejte si program. 5.5 Povely porovnávací ---------------------- Těmito povely lze porovnávat dvě hodnoty vzájemně a provádět závisle na výsledku programová větvení. Pro tyto povely není žádný analog BASIC, proto se v následujícím také žádný neuvádí. ----------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | |---------------------------------------------| | CP A | A-A | SZHV1C| BF | | CP B | A-B | SZHV1C| B8 | | CP C | A-C | SZHV1C| B9 | | CP D | A-D | SZHV1C| BA | | CP E | A-E | SZHV1C| BB | | CP H | A-H | SZHV1C| BC | | CP L | A-L | SZHV1C| BD | | CP (HL) | A-(HL) | SZHV1C| BE | | CP n | A-n | SZHV1C| FE,n | ----------------------------------------------- Symbolika těchto povelů vychází ze slova, Compare, česky porovnej. Při porovnávání CPU nedělá nic jiného, než provádí odčítání. Výsledek odečtu se však nikde neukládá, pouze Flagy se nastavují podle odpovídajícího výsledku. Jsou-li dvě hodnoty porovnávány např. A s L pomocí CP L, pak to signalizuje Zero-Flag, zda je rovnost (Z=1) nebo není (Z=0). Carry Flag naproti tomu hlásí, zda je první hodnota menší než druhá (C=1) nebo není (C=0). Příklad: CP 05 Dává následující výsledky: A<5 Z=0 C=1 A=5 Z=1 C=0 A>5 Z=0 C=0 Výsledek porovnání lze testovat podmíněný skokovým příkazem. Typické jsou při tom následující sledy povelů : str.59 Příklad: Sled povelů analog BASIC CP 05 IF A=5 GOTO... JR Z,... CP 05 IF A<>5 GOTO... JR NZ,... CP 05 IF A<5 GOTO... JR C,... CP 05 IF A>=5 GOTO... JR NC,... Chceme-li testovat zda A je skutečně větší než 5, pak se prostě porovná s 6. Stojí-li proti tomu 5 v paměťové buňce např. 8100, pak k tomu potřebujeme dva podmíněné skoky. Jako u logických povelů, namá Z80 i zde možnost porovnávat akumulátor přímo s obsahem paměťové buňky. Musí se to provádět oklikou přes HL registr. Příklad: sled povelů analog BASIC LD HL,8100 HL=8100 CP (HL) IF A> PEEK (HL) JR Z,04 JR NC,... 16bitové porovnávání -------------------- Je třeba další typická skladba při porovnávání 16bitových hodnot, protože musíme porovnávat H- a L- byty. Především se porovnávají H- byty, L- byty se pak porovnávají pouze jsou-li rovny H- byty. Porovnání BC s hodnotou 8105 vypadá následovně : Příklad: LD A,B CP 89 JR NZ,05 LD A,C CP 05 ... ... Po tomto programovém úseku jsou Flagy nastaveny jako u normálního porovnávání 8bitového, a mohou se testovat dalším podmíněným skokem. Chceme-li porovnávat obsahy dvou 16bitových registrů, pak máme elegantnější postup, když po porovnání máme zájem pouze na Carry Flagu. Provedeme zkrácenou 16bitovou subtrakci bez ukládání výsledku. Test, zda BC je menší než DE vypadá následovně: Příklad: povel analo BASIC LD A,C IF BC než 39(9)? 8002: 30 08 JR NC,800C-$ když ano, žádná cifra 8004: FE 30 CP 30 hodnota kódu je < než 30(0)? 8006: 38 04 JR C,800C-$ když ano, žádná cifra 8008: E6 0F AND 0F provést konverzi 800A: A7 AND A C=0;identifikace, že byla cifra 800B: C9 RET a RETURN 800C: 37 SCF C=1;identif., že nebyla cifra 800D: C9 RET a RETURN Porovnávací povely s automatickým Increment/Decrement (zvýšení/snížení) ----------------------------------------------------------------------- Jelikož se často stává, že musíme proledávat určitý úsek paměti po jednotlivých bytech nebo bytových sledů, má Z80 čtyři povely, které podstatně zjednodušují programování. ----------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | |---------------------------------------------| | CPI | A-(HL),HL=HL+1 | SXHY1-| ED,A1 | | | BC=BC-1 | | | | CPIR | A-(HL),HL=HL+1 | SXHY1-| ED,B1 | | | BC=BC-1,bisBC=0| | | | CPD | A-(HL),HL=HL-1 | SXHY1-| ED,A9 | | | BC=BC-1 | | | | CPDR | A-(HL),HL=HL-1 | SXHY1-| ED,B9 | | | BC=BC-1,bisBC=0| | | | | oder (HL)=A | | | ----------------------------------------------- X znamená : nastaveno když A=(HL), jinak nastaveno zpět Y znamená : nastaveno zpět, když BC=0 (po provedení), jinak nastaveno CPI znamená "Compare and Increment" CPD "Compare and Decrement" CPIR "Compare, Increment and Repeat" CPDR "Compare, Decrement and Repeat" Tyto povely porovnávají akumulátor s obsahem paměťové buňky, která je adresovaná prostřednictvim HL reg., a příslušně nastavují Flagy S, Z, H a V. "S" Flag je jednička, když A=(HL) "V" Flag je nula, když BC je nula str.61 V čistém textu : Pomocí CPIR můžete v určeném paměťovém rozsahu vyhledávat určitou hodnotu. Startovací adresu vložte do HL, délku do BC a hledanou hodnotu do A. Po provedení povelu máme dvě možnosti: .. hodnota byla nalezena -- pak je nastaven Z Flag .. hodnota nebyla nalezena v daném rozsahu paměti, pak je V Flag vynulován Následující program vyhledává v HL reg. hodnotu 0D počínaje od předem udané paměťové buňky (vyhlédání konce jednoho textového řádku). Přiklad: adresa kód povel komentář 8000: 3E 0D LD A,0D naber do akum. hledaný byte 8002: 01 00 02 LD BC,0200 délka rozsahu hex 200 byte 8005: ED B1 CPIR zvyšuj HL tak dlouho až je nalezeno 0D 8007: C9 RET pak návrat Než budete startovat program, naplňte např. HL reg. na 8100. Nezapomeňte zadat ještě do některé paměťové buňky 0D. Program se pak vrací s adresou v HL zpět, která následuje po 0D. Bitové povely ------------- Těmito povely můžete testovat jednotlivé bity, nastavovat nebo nulovat je. CPU přitom provádí prostě povel AND resp. povel OR. U povelů bitového testu se výsledek nikde neukládá, nýbrž se příslušně nastavuje Zero Flag. Z je nastaveno na 1, když je příslušný bit = 0, a vynulován když je bit = 1. ----------------------------------------------- | Mnemonic | Působení | Falgy | Hexkód | |---------------------------------------------| | Bitové testovací povely | |---------------------------------------------| | BIT 0,r | r^B0 AND 1 | ?Z1?0 |CB40+reg| | BIT 0,(HL)| (HL)^B0 AND 1 | ?Z1?0 | CB,40 | | | | | | | BIT 1,r | r^B1 AND 1 | ?Z1?0 |CB48+reg| | BIT 1,(HL)| (HL)^B1 AND 1 | ?Z1?0 | CB,4E | | | | | | | BIT 2,r | r^B2 AND 1 | ?Z1?0 |CB50+reg| | BIT 2,(HL)| (HL)^B2 AND 1 | ?Z1?0 | CB,56 | | | | | | | BIT 3,r | r^B3 AND 1 | ?Z1?0 |CB58+reg| | BIT 3,(HL)| (HL)^B3 AND 1 | ?Z1?0 | CB,5E | | | | | | | BIT 4,r | r^B4 AND 1 | ?Z1?0 |CB60+reg| | BIT 4,(HL)| (HL)^B4 AND 1 | ?Z1?0 | CB,66 | | | | | | | BIT 5,r | r^B5 AND 1 | ?Z1?0 |CB68+reg| | BIT 5,(HL)| (HL)^B5 AND 1 | ?Z1?0 | CB,6E | | | | | | | BIT 6,r | r^B6 AND 1 | ?Z1?0 |CB70+reg| | BIT 6,(HL)| (HL)^B6 AND 1 | ?Z1?0 | CB,76 | | | | | | | BIT 7,r | r^B7 AND 1 | ?Z1?0 |CB78+reg| | BIT 7,(HL)| (HL)^B7 AND 1 | ?Z1?0 | CB,7E | ----------------------------------------------- str.62 ----------------------------------------------- | Povely nastavování bitů | |---------------------------------------------| | SET 0,r | r^B0=1 | ----- |CBC0+reg| | SET 0,(HL)| (HL)^B0=1 | ----- | CB,C6 | | | | | | | SET 1,r | r^B1=1 | ----- |CBC8+reg| | SET 1,(HL)| (HL)^B1=1 | ----- | CB,CE | | | | | | | SET 2,r | r^B2=1 | ----- |CBD0+reg| | SET 2,(HL)| (HL)^B2=1 | ----- | CB,D6 | | | | | | | SET 3,r | r^B3=1 | ----- |CBD8+reg| | SET 3,(HL)| (HL)^B3=1 | ----- | CB,DE | | | | | | | SET 4,r | r^B4=1 | ----- |CBE0+reg| | SET 4,(HL)| (HL)^B4=1 | ----- | CB,E6 | | | | | | | SET 5,r | r^B5=1 | ----- |CBE8+reg| | SET 5,(HL)| (HL)^B5=1 | ----- | CB,EE | | | | | | | SET 6,r | r^B6=1 | ----- |CBF0+reg| | SET 6,(HL)| (HL)^B6=1 | ----- | CB,F6 | | | | | | | SET 7,r | r^B7=1 | ----- |CBF8+reg| | SET 7,(HL)| (HL)^B7=1 | ----- | CB,FE | ----------------------------------------------- ----------------------------------------------- | Povely pro nastavování bitů | |---------------------------------------------| | RES 0,r | r^B0=0 | ----- |CB80+reg| | RES 0,(HL)| (HL)^B0=0 | ----- | CB,86 | | | | | | | RES 1,r | r^B1=0 | ----- |CB88+reg| | RES 1,(HL)| (HL)^B1=0 | ----- | CB,8E | | | | | | | RES 2,r | r^B2=0 | ----- |CB90+reg| | RES 2,(HL)| (HL)^B2=0 | ----- | CB,96 | | | | | | | RES 3,r | r^B3=0 | ----- |CB98+reg| | RES 3,(HL)| (HL)^B3=0 | ----- | CB,9E | | | | | | | RES 4,r | r^B4=1 | ----- |CBA0+reg| | RES 4,(HL)| (HL)^B4=0 | ----- | CB,A6 | | | | | | | RES 5,r | r^B5=0 | ----- |CBA8+reg| | RES 5,(HL)| (HL)^B5=0 | ----- | CB,AE | | | | | | | RES 6,r | r^B6=0 | ----- |CBB0+reg| | RES 6,(HL)| (HL)^B6=0 | ----- | CB,B6 | | | | | | | RES 7,r | r^B7=0 | ----- |CBB8+reg| | RES 7,(HL)| (HL)^B7=0 | ----- | CB,BE | ----------------------------------------------- Symbolika je zde zcela jednoduchá : "BIT" znamená "Bit test" "SET" znamená "Set bit" "RES" znamená "Reset bit" str.63 Když chcete zjistit hodnotu, kterou má třetí bit (B2) reg. C, použijte následující povel: Příklad: BIT 2,C Pak je Zero Flag Z=0, měl-li bit hodnotu 1, jinak je Z=1. Test předznamenání ------------------- Povely bitových testů lze použít abychom zjistili znaménka u předznamenaných dvojkových čísel. Z80 má sice speciální Flag pro znaménka, který se však nenastavuje při povelech nabírání (load). Protože znaménko je jednoduše určováno nejpřednějším bitem čísla (viz dodatek A3), potřebujeme testovat pouze tento bit pomocí "BIT 7,r", je-li pak Z=0, jedná se o negativní, jinak o pozitivní číslo. Přizpůsobení znaku ASCII ------------------------ Když se přenáší větší množství znaků ASCII přes periferní zařízení, pak se užije bit B7 nejčastěji jako paritní bit. Chceme-li tyto znaky ASCII vytisknout nebo číst na displeji, pak lze B7 pomocí "RES 7,r" nastavit zpět, abychom z toho obdrželi znak ASCII. 5.6 Povely přesunu bitů ----------------------- Těmito povely můžeme posunovat obsah jednoho reg. o 1 bit doleva nebo doprava. Z registru vysunutý bit skončí v Carry Flagu. Povely posunu ------------- ----------------------------------------------- | Mnemonic | Působení | Flagy | Hexkód | |---------------------------------------------| | Bitové povely posunu | ----------------------------------------------- ----------------------------------------------- | | ----------------------- | | | | | | | | | |--| |--------| | | | RL ... | |--| C|<--|B7<---B0|<-| | | | |--| |--------| | | | Oprand | ----------------------------------------------- | RLA | s.o. | --0-0C| 17 | | RLr | s.o. | SZ0P0C|CB10+reg| | RL(HL) | s.o. | SZ0P0C| CB,16 | ----------------------------------------------- str.64 ----------------------------------------------- | | ---------------------- | | | | | | | | | |--------| |--| | | | RR ... | |->|B7--->B0|-->|C |-| | | | |--------| |--| | | | Operand | ----------------------------------------------- | RRA | s.o. | --0-0C| 1F | | RRr | s.o. | SZ0P0C|CB18+reg| | RR(HL) | s.o. | SZ0P0C| CB,1E | ----------------------------------------------- | | |-------------| | | | | | | | | |--| | |--------| | | | RLC ... | | C|<--|B7<---B0|<-| | | | |--| |--------| | | | Operand | ----------------------------------------------- | RLCA | s.o. | --0-0C| 07 | | RLCr | s.o. | SZ0P0C|CB00+reg| | RLC(HL) | s.o. | SZ0P0C| CB,06 | ----------------------------------------------- | | |-------------| | | | | | | | | | |--------| | |--| | | RRC ... | |->|B7--->B0|-->|C | | | | |--------| |--| | | | Operand | ----------------------------------------------- | RRCA | s.o. | --0-0C| 0F | | RRCr | s.o. | SZ0P0C|CB08+reg| | RRC(HL) | s.o. | SZ0P0C| CB,0E | ----------------------------------------------- | | |--| |--------| | | SLA ... | | C|<--|B7<---B0|<---0 | | | |--| |--------| | | | Operand | ----------------------------------------------- | SLAr | s.o. | SZ0P0C|CB20+reg| | SLA(HL) | s.o. | SZ0P0C| CB,26 | ----------------------------------------------- | | |----| | | | | | | | | | |--------| |--| | | SRA ... | |-->|B7--->B0|-->|C | | | | |--------| |--| | | | Operand | ----------------------------------------------- | SRAr | s.o. | SZ0P0C|CB28+reg| | SRA(HL) | s.o. | SZ0P0C| CB,2E | ----------------------------------------------- | | |--------| |--| | | SRL ... | 0-->|B7--->B0|-->|C | | | | |--------| |--| | | | Operand | ----------------------------------------------- str.65 ----------------------------------------------- | SRLr | s.o. | SZ0P0C|CB38+reg| | SRL(HL) | s.o. | SZ0P0C| CB,3E | ----------------------------------------------- U povelů "SLA" (Shift Left Arithmetic, česky přesuň aritmeticky doleva) a "SRL" (Shift Right Logical, česky přesuň logicky doprava) se z druhé strany dosouvá vždy 0 do registru. U povelů "RL" (Rotate Left, česky rotuj doleva) a "RR" (Rotate Right,česky rotuj doprava) se dosouvá vždy z druhé strany obsah Carry Flagu, zatímco z registru vyšoupnutý bit přichází právě do Carry. U "RLC" (Rotate Left Circular, česky rotuj v kruhu doleva) a "RRC" (Rotate Right Circular, česky rotuj v kruhu doprava) se bit, který bude z registru vysunut do Carry Flagu, znovu na druhé straně zasouvat opět do registru. Povel "SRA" (Shift Right Arithmetical, česky přesuň aritmeticky doprava) zasune B7 zleva do registru a B0 do Carry. Přesun doleva působí jako násobení dvěma, přesun doprava jako dělení dvěma, přičemž je ovšem dodáván pouze podíl v celých číslech (viz 1.4). Tuto skutečnost využívají protřelí Assembleroví programátoři velice často, aby programovali násobení malými konstantními hodnotami. Příklad: LD B,A SLA A ADD A,B působí jako násobení třemi, jelikož operace je prováděna : A=2*A+A Příklad: LD B,A SLA A SLA A ADD A,B působí jako násobení pěti (A=4*A+A). Výhoda takových speciálních násobících povelů spočívá v tom, že jsou nepředstavitevně rychle provedeny. Ovšem je třeba předem o to dbát, aby obsah A nebyl příliš veliký pro takové násobení, protože při "přetečení" dodává tento povelový sled nesmyslné hodnoty. 16bitový přesun --------------- Rotační povely lze použít, aby byl proveden posun o více než 8 bitů. V Carry se pak vždy po jednom bitu transportuje od jednoho k následujícimu Bytu. V následujícím příkladu se posune obsah DE registru o 1 bit doleva. Příklad: adresa kód povel komentář 8000: CB 23 SLA E B7 teď v Carry 8002: CB 12 RLD Carry teď v B0 8004: C9 RET Vyzkoušejte si program, uvidíte, jak DE je pokaždé násobeno dvěma. Má-li být 16bitové číslo, stojící v HL reg. posunuto doleva, může se použít též povel ADD HL,HL k provedení posunu. str.66 8bitové násobení ---------------- Teď vám chceme ještě ukázat jak se násobí pomocí součtu a posunu. Přitom se postupuje stejně jako u písemné formy násobení (viz 1.4). Povely posunu se dávají jednak, aby se testovalo zda na kterém místě je faktor 1 nebo 0, jednak aby bylo postaráno aby jednotlivé dílčí výsledky při sčítání byly správně "pod sebou". V následujícím příkladu se C reg. násobí s E reg., výsledek je uložen v HL (HL=C*E). Příklad: adresa kód povel komentář 8000: 16 00 LD D,00 D=0 dát počinový impuls 8002: 21 00 00 LD HL,0000 HL=0 dát počinový impuls 8005: 06 08 LD B,08 8 průběhů smyčky 8007: CB 39 SRL C Carry=B0 z C reg. 8009: 30 01 JR NC,800C-$ když B0=0 nesčítat 800B: 19 ADD HL,DE když B0=1 tak HL=HL+DE 800C: CB 23 SLA E DE posunout o 1 doleva, aby u příštího součtu bylo všechno správně pod sebou 800E: CB 12 RL D 8010: 10 F5 DJNZ 8007-$ od 8007 smyčku opakovat S přesuny se v tomto programu pracuje s početními triky, nejlépe to můžete sledovat ve způsobu zpracování po jednotlivých krocích. Zadejte jednou C=AA a E=66. Když proběhne program najdete výsledek HL=43BC. 5.7 Ostatní povely ------------------ Všechny základní důležité povely jste teď poznali. Tyto povely najdete skoro u všech mikroprocesorů, avšak často s jinými formami adresování nabo s jiným působením na Flagy. Když se teď podíváte na úplné povelové tabulky v dodatku C, zjistíte, že jsme něco vynechali, co jste ještě našli. To bychom v krátkosti probrali. Indexované adresování --------------------- Indexované adresování je možné u skoro všech povelů a sice se při tom aktivuje paměťová buňka, jejíž adresa je výsledkem ze sumy jednoho indexového registru (IX nabo IY) a z hodnoty udané v povelu. Indexované adresování je velice podobné nepřímému registrovému adresování. Příklad: LD B,(IX+3) B nabírá obsah paměť. buňky IX+3 Portové adresování ------------------ Z-80 vlastní speciální vstupní a výstupní povely, kterými lze adresovat PORTY. Tím je Z80 schopen vydávat prostřednictvím PORTů data nebo z nich data přijímat. Povely vstupními a výstupními lze adresovat až 256 PORTů. Příklad: OUT (30),A Vydává obsah akumulátoru přes PORT s adresou 30.