Instrukce 8080 – přesuny dat

První skupina instrukcí, kterou si probereme, přesouvá data. Z registrů, do registrů, i z paměti a do paměti…

Až budete psát programy v assembleru, zjistíte, že nejvíc kódu nezabírají nějaké hyper super složité výpočty, ale přesouvání dat odněkud někam. V podstatě většina činností, které mikroprocesorový systém navenek dělá, je z valné části přesouvání dat. Samotného počítání je minimum. Takže je jen logické, že začneme právě u těchto instrukcí.

MOV

Univerzální instrukce pro kopírování obsahu z jednoho registru do druhého. Instrukce má dva operandy – názvy osmibitových registrů (z minulého dílu víme, že to jsou A, B, C, D, E, H, L a M). Jako první se uvádí cílový, jako druhý zdrojový. MOV A,B tedy vezme obsah registru B a zkopíruje ho do registru A. MOV A,C zkopíruje obsah z registru C do registru A. MOV C,A přesně naopak – z registru A do registru C.

Ptáte se, kolik je kombinací? No všechny dostupné – tedy 8 x 8 = 64. Čímž neříkám, že jsou všechny smysluplné či funkční. Instrukce MOV A,A je samosebou platná, zkopíruje obsah z registru A do registru A, ale upřímně: k čemu to je?

Znovu připomínám, že M je „pseudoregistr“, který ve skutečnosti odkazuje na místo v paměti s adresou, která je uložená v dvojici registrů H, L. Takže MOV A,M znamená „vezmi obsah z paměti na adrese, která je v registrech H,L, a zkopíruj ho do registru A“. MOV M,E znamená „vezmi obsah registru E a zkopíruj ho do paměti na adresu, tkerá je v registrech H,L“. No a MOV M,M – to je výjimka. Taková instrukce neexistuje. Její operační kód zaujímá instrukce HLT, která zastaví procesor.

MVI

Tato instrukce vloží do osmibitového registru přímo zadanou hodnotu.

LXI

Tato instrukce vloží do registrového páru B, D, H nebo registru SP přímo zadanou šestnáctibitovou hodnotu.

LDA

Instrukce má jeden parametr – šestnáctibitovou adresu. Obsah paměti na téhle adrese zkopíruje do registru A

STA

Protipól předchozí instrukce – ukládá hodnotu z registru A do paměti na adresu zadanou jako operand.

A nyní si prosvištime nektera sloviška a cele fěty – pardon, zkusíme si, jak tyhle instrukce pracují. Opět k tomu použijeme interaktivní techniku – assembler ASM80.

Kód přeložte a spusťte emulaci. První instrukce je MVI A, 10. Po provedení prvního kroku bude tedy v registru A hodnota… aha! Je tam 0Ah. Emulátor totiž ukazuje všechny hodnoty hexadecimálně, zatímco v kódu je zapsaná konstanta 10, bez H na konci, takže je to tedy desítková hodnota, a 10 desítkově je v šestnáctkové soustavě 0A. (A nestěžujte si, různé způsoby zápisu konstant jsme už brali!)

Takže tedy znovu: První instrukce uloží do registru A hodnotu 0Ah (=10), druhá instrukce uloží do registru B hodnotu 14h (=20). Třetí instrukce je LXI H, číslo – mrkněte se o kousek výš… jasně! Tahle instrukce uloží zadané číslo do dvojice registrů HL. Tady je to 0040h, takže do H půjde vyšší (00) a do L nižší (40h) část čísla.

Na dalším řádku je instrukce MOV M,A. Z toho, co o ní víme, by se mělo stát následující: Obsah registru A (což je teď těch 0Ah) se zkopíruje do paměti na adresu, která je uložená v registrech HL. Tak schválně – v registrech HL je uložena hodnota 0040h, takže by se v paměti na adrese 0040h měla objevit hodnota 0Ah. Zkuste si sami – vidíte, že vlevo nahoře, v oblasti nadepsané MEMORY, se na adrese 0040h objeví právě ta hodnota 0Ah.

Bystřejší si všimli, že od adresy 0 jsou v paměti nějaká čísla. Ti, co jsou ještě bystřejší, už vědí: To je přeci ten náš program! A právě do té oblasti sáhne další instrukce – LDA 0003h vezme obsah paměti na adrese 0003h, což je zrovna shodou okolností číslo 14h (které je součástí instrukce MVI B, 20) a uloží ho do registru A.

Poslední instrukce pak uloží obsah registru A na adresu 0041h, takže od adresy 0040h budete mít vedle sebe hezky 0Ah a 14h. Máte? Skvělé, pojďme na další instrukce!

LDAX

Tak jako LDA vezme hodnotu z paměti na adrese, kterou mu zadáme, a uloží ji do A, tak i LDAX vezme hodnotu z paměti a uloží ji do A. Adresu, se kterou se bude pracovat, najde v registrovém páru B nebo D (tedy v registrech B, C, resp. D, E).

STAX

Jako má LDA svoje STA, tak má LDAX svůj STAX. Funguje stejně jako LDAX, jen přenos dat probíhá v opačném směru.

LHLD

Tahle instrukce opět pracuje s dvojicí bajtů. Jako parametr dostane adresu a vykoná následující: Do registru L zkopíruje hodnotu z paměti na dané adrese a do registru H zkopíruje hodnotu z paměti na adrese o 1 vyšší.

SHLD

Už to tak je. Instrukce Lněco mají svou obdobu v podobě Sněco. Tam, kde L z paměti čte (load), tam S do paměti zapisuje (store). Takže SHLD uloží obsah registru L na zadanou adresu, obsah registru H na adresu o 1 vyšší.

Všimněte si, že LHLD i SHLD dodržují pravidlo „malého indiána“ – na nižší adresu jde méně významný bajt.

XCHG

Poslední instrukce pro přesun dat je tak trošku výjimka. Nemá žádné operandy – to, s čím pracuje, je dáno implicitně (jsou to dvojregistry D a H). A na rozdíl od předchozích instrukcí, které kopírovaly hodnoty, tato instrukce je vyměňuje. XCHG vymění obsah registrů D a E za obsah registrů H a L. Tedy to, co bylo v D, bude teď v H – a naopak. Kdybychom udělali třeba MOV H,D a MOV L,E, dosáhli bychom něčeho jiného obsah registrů D a E by se nevyměnil, ale ZKOPÍROVAL, takže by bylo v D totéž co v H a v E totéž co v L.

Pokud chceme vyměnit údaje ve dvou registrech, musíme použít pomocný registr. Například výměnu obsahu registrů B a C zařídíme takto:

Tedy přes registr A. Jeho původní hodnotu samozřejmě ztratíme…

A opět drobná ukázka. Až si pohrajete, můžete si zkusit jedno cvičení. První samostatný program. Poslyšte zadání, je jednoduché: Program prohodí obsah registrů BC a HL.

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.

7 komentáře u Instrukce 8080 – přesuny dat

  1. Roman Bórik napsal:

    Medzi inštrukcie presunu dát možno zaradiť aj inštrukcie PCHL, SPHL a XTHL.
    Aj keď prvá z nich je prakticky inštrukciou skoku a je nakoniec uvedená aj v kapitole o skokoch.
    Ďalšie dve sa týkajú zásobníka, ale o tých v kapitole o zásobníku nie je zmienka.

    • Martin Malý napsal:

      Přemýšlím, kam dát SPHL a XTHL. Do kapitoly o přesunech je ještě brzo, buď je tedy přidám do kapitoly o zásobníku, nebo do společné kapitoly pro to, co se teď nehodilo (DAA, SPHL, XTHL, HLT, EI, DI apod.) Ještě se rozmyslím.

      • Roman Bórik napsal:

        Myslím, že kapitola o zásobníku je pre SPHL a XTHL to správne miesto.
        Inštrukcie IN a OUT, ktoré mimochodom tiež svojim spôsobom spadajú aj medzi inštrukcie presunu dát, by bolo vhodné asi dať na záver do spoločnej kapitoly spolu s HLT, EI a DI.

        • Martin Malý napsal:

          Nakonec jsem to tam přidal. Po pravdě mi tyhle dvě instrukce nepřipadají, že je nutné je probrat co nejdřív, klidně bych je nechal na později, ale na druhou stranu tam zase logicky patří. Dost jsem to zvažoval, jestli je na zájemce vysypat hned, když pro ně využití najde až bůhvíkdy (přiznejme si,tyhle instrukce nejsou z rodu běžně používaných) a klidně bych je odložil až „na někdy“. Na druhou stranu by kdekoli jinde vyžadovaly vlastní kapitolu. Takže jo, nakonec je dám sem.

  2. David Grudl napsal:

    „Pokud chceme vyměnit údaje ve dvou registrech, musíme použít pomocný registr.“

    Na osmibiťácích asi jo, na 16bitech jsem rád používal pro prohození hodnot A a B něco takového:

    A = A + B
    B = A – B
    A = A – B

Napsat komentář

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