Obsah
1. Osmibitové mikrořadiče H8/300 a H8/300L
5. Podporované adresovací režimy
6. Instrukční sada osmibitových mikrořadičů H8/300 a H8/300L
11. Booleovský procesor – manipulace s jednotlivými bity
12. Nepodmíněné skoky, vstup a výstup z podprogramů (subrutin)
14. Instrukce pro řízení procesoru
15. Instrukce pro blokový přenos dat
1. Osmibitové mikrořadiče H8/300 a H8/300L
Po popisu RISCových mikroprocesorů patřících do rodiny čipů SuperH se na chvíli budeme věnovat architektuře H8, která se sice od SuperH v několika ohledech liší, ale například již při letmém pohledu do instrukčních sad je patrné, že za vznikem obou těchto architektur stála stejná firma – Hitachi. Architektura H8 je ve skutečnosti tvořena několika řadami (rodinami) čipů s různou šířkou zpracovávaných operandů. Dnes se budeme věnovat čipům patřícím do rodiny H8/300 a H8/300L, což jsou interně osmibitové čipy, které však u některých instrukcí (zdaleka ne však u všech instrukcí) dokážou využít i šestnáctibitové operandy. Do rodiny H8/300 a H8/300L dnes patří především osmibitové mikrořadiče, které na čipu mají nainstalovánu i RAM (typická kapacita začíná na jednom kilobajtu) a ((E)P)ROM o kapacitě typicky 16 kilobajtů. Podobně jako u některých dalších mikrořadičů se i v řadě H8/300 a H8/300L používá několik instrukcí určených pro manipulaci s jednotlivými bity a pro kombinaci jednotlivých bitů s příznakem Carry flag.
Zajímavý je pohled z pozice programátora v assembleru, protože instrukční sada H8/300 kombinuje jak některé prvky známé z klasických osmibitových mikroprocesorů a mikrořadičů („nultá“ stránka paměti inspirovaná slavným MOS 6502, Booleovský procesor od 8051, nepřímé adresování taktéž převzaté z MOS 6502), tak i pokročilejší techniky typu post-inkrement adresy, pre-decrement adresy (ideální při zpracování polí, použito například v Motorole 6809 a Motorole 68000) nebo dokonce instrukci pro blokový přenos dat (známe ze slavného Zilogu Z80). K tomu připočtěme některé „RISCové“ vlastnosti – počet pracovních registrů dosáhl hodnoty šestnáct, většina instrukcí má pevnou šířku šestnácti bitů, jen některé instrukce mají šířku dvojnásobnou. Instrukční soubor je taktéž do značné míry ortogonální, což společně s velkým množstvím pracovních registrů vede k tomu, že se pro tuto rodinu procesorů mohou bez problémů používat i optimalizující céčkové překladače.
Najdeme samozřejmě i nevýhody; s některými z nich se seznámíme příště.
2. Organizace operační paměti
Vzhledem k tomu, že čipy řady H8/300 A H8/300L používají šestnáctibitové adresování a paměť RAM i ROM využívá stejný adresový prostor (nejedná se o Harvardskou architekturu), je možné adresovat buňky v rozsahu 64kB, tj. používat lze adresy 0×0000 až 0×ffff. Tento adresní prostor je rozdělen do několika bloků – 128 bajtů pro vstupně/výstupní registry (mikrořadiče), RAM umístěná přímo na čipu o velikosti typicky začínající na 1kB, ((E)P)ROM umístěná taktéž na čipu o typické velikosti 16kB a konečně 42 bajtů obsahujících vektory používané při přerušení (ovšem u některých mikrořadičů nemusí být všechny vektory obsazeny). Paměť RAM je mapována na horní adresy a pro posledních 256 bajtů lze použít adresování s použitím osmibitové adresy. Ušetří se tím programový kód (kratší instrukce) i několik taktů při běhu programu. ROM je naproti tomu umístěna na nižších adresách. Zásobník je samozřejmě mapován do RAM a roste směrem k nižším adresám:
0x0000 +--------------------------------+ | vektory přerušovacích rutin | 0x002A +--------------------------------+ | | | | | oblast s namapovanou (E(P))ROM | | | | | 0x4000 +--------------------------------+ (hranice se může lišit) | | | | | prázdná oblast | | | | | 0xfb00 +--------------------------------+ (hranice se může lišit) | | | | | oblast s namapovanou RAM | (0xff00) | | začátek oblasti adresované přes osmibitovou konstantu | | 0xff80 +--------------------------------+ (může se lišit) | I/O registry (128 bajtů) | 0xffff +--------------------------------+
3. Pracovní registry
Jádra řady H/300 a H/300L obsahují šestnáct osmibitových pracovních registrů, přičemž vždy dva sousední registry mohou tvořit šestnáctibitový registrový pár. Ostatně nejedná se o žádnou novinku, protože podobný koncept se objevil i v procesorech Intel 8080 a později byl rozšířen o možnosti dalšího párování registrů na architektuře i386. Nicméně se vraťme k řadě H8. Pojmenování pracovních registrů je zřejmé z následující tabulky:
8bit registr | 8bit registr | 16bitový pár |
---|---|---|
R0H | R0L | R0 |
R1H | R1L | R1 |
R2H | R2L | R2 |
R3H | R3L | R3 |
R4H | R4L | R4 |
R5H | R5L | R5 |
R6H | R6L | R6 |
R7H | R7L | R7 (též SP) |
Poslední registrový pár lze použít i ve funkci šestnáctibitového ukazatele na vrchol zásobníku (zásobník roste od vyšších adres směrem k adresám nižším).
4. Speciální registry
Kromě pracovních registrů u těchto procesorů nalezneme i obligátní registr PC, který zde má šířku šestnácti bitů a dokáže tedy adresovat celých 64 kB.
Posledním registrem je registr CCR (Condition Code Register), přičemž každý bit tohoto registru má odlišný význam:
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ | I | U | H | U | N | Z | V | C | +---+---+---+---+---+---+---+---+
Význam jednotlivých bitů stavového a řídicího registru je popsán v následující tabulce:
Index | Příznak | Význam zkratky | Poznámka |
---|---|---|---|
7 | I | interrupt | maskování neboli zákaz IRQ (přerušení) |
6 | U | user bit | bit, který lze nastavit či testovat instrukcemi LDC, STC, ANDC, ORC a XORC |
5 | H | half carry | přenos z bitu číslo 3 do bitu číslo 4 (použit instrukcemi DAA a DAS) |
4 | U | user bit | bit, který lze nastavit či testovat instrukcemi LDC, STC, ANDC, ORC a XORC |
3 | N | negative | výsledek ALU operace je záporný |
2 | Z | zero | výsledek ALU operace je nulový |
1 | V | overflow | přetečení (znaménková aritmetika, signed) |
0 | C | carry | přenos (bezznaménková aritmetika, unsigned) |
Povšimněte si, že počet pracovních registrů je na osmibitový procesor velmi vysoký, což dále umocňuje fakt, že se každý z pracovních registrů (či párů) může použít i pro adresování – neexistují zde tedy rozdíly mezi „akumulátorem“ a „indexovým registrem“.
5. Podporované adresovací režimy
Adresovací režimy podporované v procesorech řady H8/300 a H8/300L se v mnoha ohledech podobají režimům, které jsme si již popsali u RISCových procesorů SuperH, samozřejmě s tím rozdílem, že adresy jsou zde pouze šestnáctibitové a v několika případech dokonce jen osmibitové. Ostatně se podívejme na následující tabulku s výčtem všech podporovaných adresovacích režimů:
Název režimu | Zápis v asm | Význam |
---|---|---|
Register direct | Rn | většina instrukcí akceptuje pouze osmibitový registr |
Register indirect | @Rn | Rn je šestnáctibitový registr obsahující adresu |
Register indirect with displacement | @(d:16,Rn) | jako předchozí režim, ovšem navíc se 16bitovým offsetem |
Register indirect with post-increment | @Rn+ | pro instrukce MOV, posun o jeden či dva bajty podle typu přenosu |
Register indirect with pre-decrement | @-Rn | pro instrukce MOV, posun o jeden či dva bajty podle typu přenosu |
Absolute address | @aa:8 | za instrukcí následuje osmibitová konstanta, přičte se k ní 0×ff00 |
Absolute address | @aa:16 | za instrukcí následuje šestnáctibitová konstanta |
Immediate | #xx:8 | za instrukcí následuje osmibitová konstanta |
Immediate | #xx:16 | za instrukcí následuje šestnáctibitová konstanta |
Program-counter relative | @(d:8,PC) | použito pro relativní skoky v rozsahu –126 do 128 |
Memory indirect | @@aa:8 | použito u JMP a JSR, na adrese je uložen cíl skoku |
Zajímavý je režim s osmibitovou absolutní adresou. V tomto režimu lze adresovat jen paměť na adresách 0×ff00 až 0×ffff, což je RAM. Naproti tomu poslední režim používá adresy skoků uložené na adresách 0×0000 až 0×00ff, kde je mapována ROM. Mimochodem, oba dva zmíněné režimy připomínají adresování přes nultou stránku paměti známé z mikroprocesorů MOS 6502.
6. Instrukční sada osmibitových mikrořadičů H8/300 a H8/300L
Osmibitové mikrořadiče řady H8/300 a H8/300L obsahují celkem 57 instrukcí, i když způsob počítání instrukcí se nám může v některých případech zdát poněkud zvláštní (instrukce PUSH a POP jsou vlastně interně reprezentovány instrukcí MOV, všechny varianty podmíněných skoků jsou započteny jen jednou atd.). Instrukce můžeme podle jejich funkce rozdělit do několika kategorií vypsaných v následující tabulce:
Skupina | Instrukce | Počet |
---|---|---|
Přenos dat | MOV, PUSH, POP | 3 (1) |
Aritmetické | ADD, SUB, ADDX, SUBX, INC, DEC, ADDS, SUBS, DAA, DAS, MULXU, DIVXU, CMP, NEG | 14 |
Logické | AND, OR, XOR, NOT | 4 |
Posuny a rotace | SHAL, SHAR, SHLL, SHLR, ROTL, ROTR, ROTXL, ROTXR | 8 |
Bitové manipulace | BSET, BCLR, BNOT, BTST, BAND, BIAND, BOR, BIOR, BXOR, BIXOR, BLD, BILD, BST, BIST | 14 |
Nepodmíněné skoky | JMP, BSR, JSR, RTS | 4 |
Podmíněné skoky | Bcc (celkem 16 variant) | 1 |
Řízení procesoru | RTE, SLEEP, LDC, STC, ANDC, ORC, XORC, NOP | 8 |
Blokové přenosy | EEPMOV | 1 |
Celkem | 57 (55) |
7. Instrukce pro přenosy dat
Podrobnější vysvětlení jednotlivých instrukcí z instrukční sady začneme popisem těch instrukcí, které jsou primárně určeny pro přenosy dat, a to jak mezi pracovními registry, tak i mezi vybraným pracovním registrem a bajtem (či dvěma sousedními bajty) uloženými v operační paměti. Do této skupiny instrukcí patří zejména instrukce MOV, resp. přesněji řečeno její varianty MOV.B a MOV.W, a taktéž dvojice instrukcí PUSH a POP. Tyto dvě instrukce vždy pracují s šestnáctibitovými registry, nikoli s registry osmibitovými:
# | Instrukce | Popis | Poznámka |
---|---|---|---|
1 | MOV.B | přenos dat mezi osmibitovými registry či registrem a pamětí | lze použít i adresování @aa:8 |
2 | MOV.W | přenos dat mezi 16bitovými registry či registrem a pamětí | lze použít i adresování @-Rn či @Rn+ |
3 | MOV.B #xx, Rn | uložení osmibitové konstanty do registru | šířka slova je 16 bitů |
4 | MOV.W #xxxx, Rn | uložení šestnáctibitové konstanty do registru | šířka slova je 32 bitů |
5 | PUSH | uložení 16bitového registru na zásobník | ekvivalentem je instrukce MOV.W Rn, @-SP |
6 | POP | obnovení 16bitového registru ze zásobníku | ekvivalentem je instrukce MOV.W@SP+, Rn |
U instrukcí PUSH a POP si povšimněte, že zásobník skutečně roste směrem k nižším adresám, podobně jako je tomu i u mnoha dalších procesorových architektur.
Ve skutečnosti ještě existuje jedna další instrukce určená pro přenosy dat. Jedná se o instrukci nazvanou EEPMOV, která je kvůli své výjimečnosti samostatně popsána v patnácté kapitole.
8. Aritmetické operace
Skupina aritmetických instrukcí je na procesorech H8/300 poměrně rozsáhlá, což je ostatně patrné i při letmém pohledu na následující tabulky. Většina instrukcí je omezena na osmibitové operandy, jen několik vybraných instrukcí dokáže pracovat i se šestnáctibitovými pracovními registry. Základ samozřejmě tvoří instrukce pro součet a rozdíl. Povšimněte si, že tyto instrukce existují v několika variantách, a to podle toho, jakého typu jsou operandy (může se jednat o osmibitový či šestnáctibitový registr popř. o osmibitovou konstantu) či zda se má při sčítání navíc přičíst i příznak přenosu a při odečítání naopak odečíst tzv. výpůjčka (borrow je svým významem negace carry). Instrukce ADDS a SUBS jsou vlastně obdobou instrukcí s osmibitovou konstantou, ovšem s tím rozdílem, že prvním operandem je šestnáctibitový registr a druhým operandem konstanta 1 či 2 (větší konstanty se do instrukčního slova již nevlezou):
# | Instrukce | Popis | Poznámka |
---|---|---|---|
1 | ADD | součet Rd = Rd + Rs | 8bit i 16bit |
2 | ADD | součet Rd = Rd + konstanta | jen pro osmibitový cílový registr (konstanta je ve spodním bajtu instrukce) |
3 | ADDX | součet Rd = Rd + Rs + Carry | 8bit i 16bit |
4 | ADDX | součet Rd = Rd + konstanta + Carry | dtto jako ADD |
5 | ADDS | součet Rd = Rd + 1 nebo Rd = Rd + 2 | 16bit, konstanta je uložena v instrukci |
6 | SUB | rozdíl Rd = Rd – Rs | 8bit i 16bit |
7 | SUB | rozdíl Rd = Rd – konstanta | jen pro osmibitový cílový registr (konstanta je ve spodním bajtu instrukce) |
8 | SUBX | rozdíl Rd = Rd – Rs – Carry | 8bit i 16bit |
9 | SUBX | rozdíl Rd = Rd – konstanta – Carry | dtto jako ADD |
10 | SUBS | rozdíl Rd = Rd – 1 nebo Rd = Rd – 2 | 16bit, konstanta je uložena v instrukci |
Pro podporu výpočtů s hodnotami reprezentovanými v BCD kódu (dvojice číslic 00 až 99) jsou určeny instrukce pro úpravu výsledků součtu a rozdílu na základě hodnoty stavového bitu half carry. Z určitého pohledu se sice jedná o anachronismus, nicméně i dnes nalezneme čipy (RTC, některé čtečky čárových kódů, některé numerické displeje), které BCD stále používají:
# | Instrukce | Popis | Poznámka |
---|---|---|---|
11 | DAA | úprava výsledku po součtu dvou BCD čísel | jen pro osmibitový cílový registr |
12 | DAS | úprava výsledku po rozdílu dvou BCD čísel | jen pro osmibitový cílový registr |
Při implementaci programových smyček je možné s výhodou použít instrukce INC a DEC, které zvýší či sníží obsah vybraného osmibitového pracovního registru o jedničku a popř. nastaví příznak nulovosti. Tyto instrukce se naopak NEpoužívají při adresování polí, protože procesory H8/300 mají speciální adresovací režimy s post-inkrementem a pre-dekremenentem adresy:
# | Instrukce | Popis | Poznámka |
---|---|---|---|
13 | INC | inkrementace Rd = Rd + 1 | jen pro osmibitový cílový registr |
14 | DEC | dekrementace Rd = Rd – 1 | jen pro osmibitový cílový registr |
Instrukce pro násobení a dělení jsou omezeny na násobení dvou osmibitových operandů se šestnáctibitovým výsledkem. Dělení naopak používá šestnáctibitový dělenec a výsledkem dělení je podíl i zbytek (oba jen osmibitové, což znamená, že ne všechny vstupy do této instrukce jsou korektní):
# | Instrukce | Popis | Poznámka |
---|---|---|---|
15 | MULXU | součin Rd = Rd × Rs | vstupem jsou osmibitové registry, výstup 16bitový |
16 | DIVXU | podíl Rd = Rd ÷ Rs | vstupem je 16bitový registr, výstup 8bit podíl+8bit zbytek |
Zbývající dvě instrukce slouží pro porovnání obsahů dvou registrů popř. pro porovnání obsahu osmibitového registru s konstantou. Po porovnání se nastaví příznaky stejným způsobem, jako při výpočtu rozdílu. Poslední instrukce je velmi jednoduchá, protože slouží pro změnu znaménka hodnoty uložené ve vybraném osmibitovém pracovním registru:
# | Instrukce | Popis | Poznámka |
---|---|---|---|
17 | CMP | Rd – Rs s nastavením příznaků | 8bit i 16bit |
18 | CMP | Rd – konstanta s nastavením příznaků | jen pro osmibitový cílový registr |
19 | NEG | výpočet Rd = -Rd | jen pro osmibitový cílový registr |
9. Logické operace
Instrukce pro provedení logických operací tvoří velmi malou skupinu, protože v ní nalezneme pouze čtyři instrukce, přičemž první tři instrukce existují ve dvou variantách. Všechny logické operace probíhají nad osmibitovými operandy, přičemž prvním zdrojovým a současně i cílovým operandem je osmibitový pracovní registr a druhým operandem může být taktéž pracovní registr popř. osmibitová konstanta (ta je součástí šestnáctibitového instrukčního slova):
# | Instrukce | Popis | Poznámka |
---|---|---|---|
1 | AND | Rd = Rd ∧ Rs | jen osmibitové registry |
2 | AND | Rd = Rd ∧ konstanta | konstanta tvoří spodní bajt instrukce |
3 | OR | Rd = Rd ∨ Rs | jen osmibitové registry |
4 | OR | Rd = Rd ∨ konstanta | konstanta tvoří spodní bajt instrukce |
5 | XOR | Rd = Rd ⊕ Rs | jen osmibitové registry |
6 | XOR | Rd = Rd ⊕ konstanta | konstanta tvoří spodní bajt instrukce |
7 | NOT | Rd = ¬ Rd | jen osmibitový registr |
10. Bitové posuny a rotace
V assembleru se poměrně často používají instrukce provádějící takzvané bitové rotace. O co se vlastně jedná? Jde o posun všech bitů v některém z pracovních registrů (na H8/300 pouze osmibitových), ovšem takovým způsobem, že se jedná o uzavřenou smyčku, tj. obsah bitu, který by se provedením posunu ztratil (byl by vysunut), je naopak zkopírován na vstup. Pro takto chápanou bitovou rotaci existují dvě instrukce, první pro rotaci obsahu pracovního registru doleva a druhá pro rotaci doprava. Každá instrukce způsobí rotaci pouze o jeden bit. Nákres rotace doleva i doprava, je naznačen na obrázku:
+---+---+---+---+---+---+---+---+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |-->--+ +---+---+---+---+---+---+---+---+ | ^ | | | +-----------------------------------+
+---+---+---+---+---+---+---+---+ +--<--| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | +---+---+---+---+---+---+---+---+ | ^ | | +-----------------------------------+
Kromě běžných bitových rotací popsaných v předchozím odstavci se setkáme i s rotacemi prováděnými přes příznak přenosu (Carry flag). V podstatě se jedná o rozšíření bitové šířky rotovaného registru o jeden bit, který je představovaný právě příznakem přenosu, tj. neprovádí se rotace osmi bitů, ale bitů devíti. Použití těchto typů rotací spočívá například v implementaci víceslovní aritmetiky (rotuje se přes větší množství slov), popř. při požadavku na vložení hodnoty příznaku přenosu do určeného bitu pracovního registru (booleovské operace). Nákres rotace doleva i doprava přes příznak přenosu, je naznačen na obrázku:
+---+---+---+---+---+---+---+---+ +-------+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |--->---| Carry | +---+---+---+---+---+---+---+---+ +-------+ ^ | | v +-----------------------------------------+
+-------+ +---+---+---+---+---+---+---+---+ + Carry |---<---| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +-------+ +---+---+---+---+---+---+---+---+ | ^ | | +-----------------------------------------+
Další dvě strojové instrukce provádějí bitový posun doleva a doprava. Od rotací se bitové posuny odliší především tím, že se při posunu doleva do nejnižšího bitu vždy vloží nula a při posunu doprava se do nejvyššího bitu taktéž uloží nula (při rotacích se naproti tomu namísto nuly použil příznak přenosu či zrovna vysunutý bit). K čemu je možné tyto instrukce využít? Typickým příkladem je optimalizace násobení mocninou dvou či naopak dělení mocninou dvou (instrukce SHLR). Musíme však mít na paměti důležitý fakt, že SHLR lze použít pouze pro hodnoty bez znaménka (unsigned).
K výše popsané šestici bitových rotací a posunů přidejme ještě aritmetické posuny. Ty jsou podobné logickým posunům, ovšem při aritmetickém posunu doprava obsah nejvyššího bitu zůstává za všech okolností zachován (a samozřejmě je ještě zkopírován do druhého nejvyššího bitu). Pokud si uvědomíme, jakým způsobem jsou reprezentovány hodnoty v systému dvojkového doplňku, je zřejmé, že tato instrukce ve většině případů (99,99% u osmibitových čísel) provádí dělení dvěma, a to i pro záporné hodnoty.
Ve skupině instrukcí určených pro bitové posuny a rotace nalezneme celkem osm různých variant, které jsou vypsány v následující tabulce. Podobně jako tomu bylo v případě logických instrukcí, i tato skupina operací manipuluje s osmibitovými registry, navíc jsou všechny posuny a rotace provedeny o jediný bit (v instrukčním slovu není dostatek místa pro uložení počtu bitů, navíc procesor pravděpodobně ani neobsahuje barrel shifter s potřebnými propojeními):
# | Instrukce | Popis | Poznámka |
---|---|---|---|
1 | SHAL | aritmetický posun registru Rd doleva | |
2 | SHAR | aritmetický posun registru Rd doprava | |
3 | SHLL | logický posun registru Rd doleva | |
4 | SHLR | logický posun registru Rd doprava | |
5 | ROTL | rotace registru Rd doleva | |
6 | ROTR | rotace registru Rd doprava | |
7 | ROTXL | rotace registru Rd doleva přes carry flag | |
8 | ROTXR | rotace registru Rd doprava přes carry flag |
11. Booleovský procesor – manipulace s jednotlivými bity
V instrukční sadě nalezneme i čtrnáct instrukcí, s jejichž využitím je na jádrech H/300 a H/300L implementován takzvaný Booleovský procesor, tj. (zjednodušeně řečeno) procesor omezený na manipulaci s jednotlivými bity. Tento procesor používá namísto akumulátoru příznakový bit Carry Flag, který se využívá jak ve funkci jednoho vstupního operandu, tak i pro uložení výsledku operace (v jednom případě se používá i Zero flag). Podívejme se nyní, které instrukce patří do této skupiny:
# | Instrukce | Popis |
---|---|---|
1 | BCLR | bitn cíle = 0 |
2 | BSET | bitn cíle = 1 |
3 | BNOT | bitn cíle = ¬ bitn cíle |
4 | BTST | Zero flag = ¬ bitn cíle |
5 | BAND | Carry flag = Carry flag ∧ bitn cíle |
6 | BIAND | Carry flag = Carry flag ∧ ¬ bitn cíle |
7 | BOR | Carry flag = Carry flag ∨ bitn cíle |
8 | BIOR | Carry flag = Carry flag ∨ ¬ bitn cíle |
9 | BXOR | Carry flag = Carry flag ⊕ bitn cíle |
10 | BIXOR | Carry flag = Carry flag ⊕ ¬ bitn cíle |
11 | BLD | Carry flag = bitn cíle |
12 | BILD | Carry flag = ¬ bitn cíle |
13 | BST | bitn cíle = Carry flag |
14 | BIST | bitn cíle = ¬ Carry flag |
Poznámka: n může být specifikováno konstantou 0 – 7 (je uložena v instrukčním slovu) či v pracovním registru.
12. Nepodmíněné skoky, vstup a výstup z podprogramů (subrutin)
Další čtyři instrukce slouží pro provedení nepodmíněného skoku, skoku do podprogramu a návratu z podprogramu. Instrukce skoku má mnemotechnickou zkratku JMP a provádí skok na zadanou adresu, která může být specifikována buď přímo (16 bitů) či nepřímo (v registru). Alternativně lze použít instrukci BSR, v níž je adresa skoku zadaná pouze relativně osmibitovým offsetem, což umožňuje jak konstrukci kódu nezávislého na hodnotě své počáteční adresy (PIC), tak i zkrácené skoky v rámci jednoho podprogramu. Instrukce pro skok do podprogramu JSR provede před vlastním skokem uložení 16bitové návratové adresy na zásobník. O návrat z podprogramu, tj. o vyzvednutí návratové adresy ze zásobníku a skoku na tuto adresu, se stará instrukce nazvaná RTS (tato instrukce je podle očekávání bez operandů).
# | Instrukce | Popis | Poznámka |
---|---|---|---|
1 | JMP | nepodmíněný skok | adresa: registr, @aa:16, @@aa:8 |
2 | BSR | skok do podprogramu | relativní osmibitová adresa |
3 | JSR | skok do podprogramu | adresa: registr, @aa:16, @@aa:8 |
4 | RTS | návrat z podprogramu |
Poznámka: pokud se v instrukcích JMP a JSR použije šestnáctibitová adresa, má celá instrukce délku 32 bitů, protože druhých šestnáct bitů je pochopitelně nutné rezervovat pro uložení adresy skoku.
13. Podmíněné skoky
Podmíněné skoky se u architektury H8/300 jmenují branch, nikoli jump, což ostatně platí i pro celou řadu dalších mikroprocesorů, počínaje Motorolou 6800 a MOS 6502 až po výkonné 32bitové RISCové čipy. V instrukčním souboru nalezneme celkem šestnáct instrukcí pro podmíněné skoky, ovšem první dvě instrukce vlastně ve skutečnosti žádnou podmínku netestují, protože BRA je proveden vždy a BRN naopak nikdy. Další skupina podmíněných skoků se používá pro test provedení či naopak neprovedení skoku hodnotu jednoho z příznakových bitů zero, overflow či negative. Další čtyři podmíněné skoky se většinou používají při porovnávání dvou hodnot bez znaménka (unsigned). V těchto případech se testují stavy příznakových bitů carry a zero, přesněji řečeno kombinace těchto bitů. Poslední čtyři podmíněné skoky se používají pro porovnávání hodnot se znaménkem (signed). V těchto případech se namísto příznakových bitů carry a zero testují kombinace bitů negative, overflow a zero:
# | Instrukce | Význam zkratky | Podmínka | Typ |
---|---|---|---|---|
1 | BRA | Always | vždy (true) | skok proveden vždy |
2 | BRN | Never | nikdy (false) | skok neproveden |
3 | BHI | High | C or Z == 0 | > unsigned aritmetika |
4 | BLS | Low or Same | C or Z == 1 | ≤ unsigned aritmetika |
5 | BCC | Carry Clear | C == 0 | < unsigned aritmetika |
6 | BCS | Carry Set | C == 1 | ≥ unsigned aritmetika |
7 | BNE | Not Equal | Z == 0 | = nerovnost operandů |
8 | BEQ | Equal | Z == 1 | ≠ rovnost operandů |
9 | BVC | Overflow Clear | V == 0 | test jediného příznaku |
10 | BVS | Overflow Set | V == 1 | test jediného příznaku |
11 | BPL | Plus | N == 0 | test jediného příznaku |
12 | BMI | Minus | N == 1 | test jediného příznaku |
13 | BGE | Greater or Equal | N ⊕ V == 0 | ≥ signed aritmetika |
14 | BLT | Less Than | N ⊕ V == 1 | < signed aritmetika |
15 | BGT | Greater Than | Z ∨ (N ⊕ V) == 0 | > signed aritmetika |
16 | BLE | Less or Equal | Z ∨ (N ⊕ V) == 1 | ≤ signed aritmetika |
14. Instrukce pro řízení procesoru
V této kapitole jsou popsány různé instrukce určené pro řízení procesoru. Jak je z tabulky patrné, nachází se zde ve skutečnosti několik skupin instrukcí, přičemž poslední skupina slouží pro manipulaci s příznakovým registrem CCR:
# | Instrukce | Popis |
---|---|---|
1 | NOP | pouhé zvýšení hodnoty PC o 2 |
2 | RTE | návrat z rutiny pro obsluhu výjimek |
3 | SLEEP | přepnutí do režimu nízké spotřeby (mikrořadiče) |
4 | LDC | přenos osmibitového registru či konstanty do CCR |
5 | STC | uložení CCR do vybraného osmibitového registru |
6 | ANDC | CCR = CCR ∧ osmibitová konstanta (maska pro nulování bitů) |
7 | ORC | CCR = CCR ∨ osmibitová konstanta (maska pro nastavení bitů) |
8 | XORC | CCR = CCR ⊕ osmibitová konstanta (maska pro negaci bitů) |
15. Instrukce pro blokový přenos dat
Nejsložitější instrukce se jmenuje EEPMOV a slouží pro implementaci blokového přenosu dat:
# | Instrukce | Popis |
---|---|---|
1 | EEPMOV | blokový přenos dat |
Tato instrukce využívá trojici pracovních registrů, a to následovně:
while R4L > 0: @R6+ = @R5+ ; přenos z adresy uložené v R5 na adresu uloženou v R6 R4L--
Jinými slovy:
- R4L na začátku obsahuje počet přenesených prvků (max 256 slov)
- R5 obsahuje počáteční adresu přenášeného bloku
- R6 obsahuje počáteční adresu cíle přenosu
16. Odkazy na Internetu
- H8 Family
https://en.wikipedia.org/wiki/H8_Family - H8/300 and H8/300L
http://nah6.com/~itsme/download/ibutton/h8_8bit.pdf - H8 Family
https://www.renesas.com/en-us/products/microcontrollers-microprocessors/h8.html - (GCC) Status of Supported Architectures from Maintainers' Point of View
https://gcc.gnu.org/backends.html - (GCC) H8/300 Options
https://gcc.gnu.org/onlinedocs/gcc/H8_002f300-Options.html#H8_002f300-Options - GCC for SuperH,H8/300,AVR
http://mes.osdn.jp/h8/gcc.html - H8/3802, 38002S, 38004, 38104 (manuály k čipům)
https://www.renesas.com/en-us/document/hw-manual?hwLayerShowFlg=true&prdLayerId=184&layerName=H8%252F3802%252C%2B38002S%252C%2B38004%252C%2B38104&coronrService=document-prd-search&hwDocUrl=%2Fen-us%2Fdoc%2Fproducts%2Fmpumcu%2F001%2Frej09b0024_h83802.pdf&hashKey=c5e1fa0a18c01e6c789bc7b5c0184ed9 - Addressing mode (Wikipedia)
https://en.wikipedia.org/wiki/Addressing_mode - Renesas SH Instruction Set Summary
http://shared-ptr.com/sh_insns.html - SH-4 RISC Processor by HITACHI
http://www.cs.umd.edu/~meesh/cmsc411/website/projects/risc/risc.htm - SH-4 RISC Processor
http://www.cs.umd.edu/~meesh/cmsc411/website/projects/risc/sh-4.htm - SuperH RISC engine Family Features
https://www.renesas.com/en-us/products/microcontrollers-microprocessors/superh/superh-features.html - Orthogonal instruction set
https://en.wikipedia.org/wiki/Orthogonal_instruction_set - Status Register
https://en.wikipedia.org/wiki/Status_register - 6800 Instruction Set
http://www.electronics.dit.ie/staff/tscarff/6800/Instructions/instructions.htm - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - Calling subroutines
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cihcfigg.htm - Art of Assembly – Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter6/CH06–2.html - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - ARM subroutines & program stack
http://www.toves.org/books/armsub/ - Programming from the Ground Up Book – Summary
http://savannah.nongnu.org/projects/pgubook/ - The 6502 overflow flag explained mathematically
http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html