Instrukční soubor AVR

Z MAM wiki

Přejít na: navigace, hledání

AVR Instruction Set Manual

Doporučuju stáhnout tento instrukční soubor, obsahuje přehled všech příkazů:

Zde na této stránce je popis instrukcí z různých trochu netradičních pohledů, které doplňují systematický popis v běžných manuálech. Dále uvedené skupiny instrukcí se různě překrývají - jsou to skupiny, které spojuje nějaká zajímavá vlastnost.

Obsah

[editovat] Jednoduché aritmerické instrukce

Řada aritmetických a logických instrukcí pracuje s jedním či se dvěma osmibitovými registry (ze 32 pracovních registrů) a bez záludností udělá přesně to, co čekáte: ADD, SUB, AND, OR, INC, DEC.

[editovat] Instrukce, které pracují jen s R16 až R31

Některé instrukce nelze použít pro registry R0 až R15. Jsou to ty, které obsahují osmibitovou konstantu: LDI, SUBI, ORI, ANDI, SBCI a CPI (a jejich případná synonyma, viz níže: SBR, CBR a SER). V 16-i bitovém kódu instrukce totiž už na číslo registru nezbylo dost místa.

[editovat] 16-i bitové instrukce

AVR je osmibitová architektura, ale některé instrukce pracují s dvojicí registrů jako s jedním 16-i bitovým:

  • MOVW přesune dvojici do jiné
  • ADIW a SBIW ke dvojici přičtou či od ní odečtou konstantu 0 až 63
  • 16-i bitový výsledek mají všechna násobení (MUL a 5 dalších instrukcí)
  • řada instrukcí používá dvojici k adresování (jako registry X, Y a Z)

Dále jsou některé dvojice osmibitových instrukcí navrženy tak, aby daly dohromady šestnáctibitovou:

  • SUB+SBC a SUBI+SBCI je šestnáctibitové odečtení dvojice registrů či konstanty, dokonce včetně nastavení příznaku Zero dle všech 16 bitů výsledku. ADD+ADC ovšem nastaví Zero jen dle horních 8 bitů.
  • CP+CPC je šestnáctibitové porovnání velikosti čísel, opět včetně nastavení Zero dle všech 16 bitů.

Šestnáctibitové logické operace lze samozřejmě udělat tak, že dvakrát použijeme instrukce jako AND, OR, EOR atp. Příznak Zero ale bude odpovídat jen poslední instrukci (šestnáctibitová specialita je jen u výše zmíněných tří instrukcí SBC, SBCI a CPC). Bitové posuvy lze udělat takto:

  • LSL+ROL je "šestnáctibitové LSL"
  • LSR+ROR je "šestnáctibitové ROR", ASR+ROR je "šestnáctibitové ASR" (na rozdíl od všech ostatních případů musíme u posunů doprava samozřejmě začít vyššími registry).

(Šestnáctibitové rotace asi nezbývá než udělat jako BST+LSL+ROL+BLD atp.)

[editovat] "Nadbytečné" instrukce

Některé instrukce ve skutečnosti "neexistují" - assembler je sice jako instrukce zná, ale překládá je jako speciální případ nějaké jiné instrukce. Vhodné používání těchto synonymních instrukcí může být užitečné, chceme-li lépe vystihnout smysl programu, ale trochu nás matou, chceme-li se seznámit s možnostmi procesoru:

  • LSL R (posun o bit doleva) je ve skutečnosti ADD R, R
  • ROL R (rotace vlevo přes Carry bit) je ve skutečnosti ADC R, R
  • SBR (set bits) je synonymum k ORI ("or" s konstantou)
  • CBR (clear bits) je implementováno pomocí ANDI ("and" s konstantou)
  • CLR je EOR (xor). Šlo by udělat i jako ANDI, ale ne pro všechny registry. Podobně LDI, to by nenastavilo status registr. Zajímavé je SUB - navíc vynuluje "C" a "H".
  • SER (set register, nastavení na samé 1) je jen zvláštní případ LDI (ulož konstantu do registru)
  • BRxx (branch if ...) - všech těchto 18 instrukcí (BREQ, BRNE atp.) jsou speciální případy BRBS a BRBC, skok podle stavu jednoho bitu ve stavovém registru - dokonce i BRGE a BRLT, kde dokumentace říká "N xor V", ale ve skutečnosti je to "S".
  • SEC,CLC,...,SEH,CLH - těchto 16 instrukcí, dokonce včerně SEI a CLI (povolení a zakázání přerušení), jsou jen speciální případy BSET a BCLR - nastavení bitu stavového registru

Víme-li o těchto synonymech, snáze pak zvládneme jemné detaily v chování instrukcí - víme, že u synonym (či různých speciálních případů téže instrukce) budou detaily stejné.

Některé instrukce by naopak na první pohled mohly být synonymní s jinými, ale nejsou:

  • DEC není implementováno jako SUBI 1 (odečtení konstanty). DEC je možno použít pro všech 32 registrů, zatímco SUBI jen pro horních 16, a také se liší způsob nastavení stavového registru (SUBI nastaví "Carry", DEC nikoli)
  • INC také není implementováno jako přičtení 1, protože instrukce pro osmibitové přičtení konstanty ani není. Také není synonymní s SUBI 255 (odečtení -1 s využitím přetečení), opět se liší příznaky a použitelné registry.
  • SBIW ani ADIW nejsou překládány dvojicí SUBI+SBCI. Rychlost by byla stejná. Dvojice SUBI+SBCI zabere 2x více místa, ale umožní libovolnou konstantu (ne jen 0..63), pracuje od r16 výše (ne až od r24) a jinak nastaví příznaky.
  • SBI a CBI by nemohly být implementovány pomocí ORI či SBR a ANDI či CBR, protože vůbec nepracují s R0 až R31, ale s úplně jinými registry, totiž I/O registry jako DDRB a PORTB (shodou okolností je těchto použitelných I/O registrů také 32). Je pravda, že tyto zcela oddělené skupiny registrů (pracovní registry R0 až R31 a I/O registry) jsou také někdy ve stejné skupině, totiž při alternativním přístupu přes adresový prostor RAM, ale přímo naadresovat přes tento prostor určitý registr mohou jen instrukce STS a LDS, které by mohly sloužit leda tak jako delší synonymum k MOV, IN a OUT.

[editovat] Instrukce, které nemění stavový registr

Takové instrukce můžeme vložit mezi vyhodnocení podmínky a skok. Také je využijeme v rychlé obsluze přerušení, chceme-li ušetřit čas tím, že stavový registr neuložíme hned na začátku obsluhy přerušení, či dokonce vůbec. Jsou to například tyto instrukce:

  • CBI, SBI - umožní nám z přerušení rychle nastavit výstupy, v kombinaci s SBIC a SBIS dokonce podle vstupů
  • SWAP
  • LD, ST, MOV a další přesuny
  • IN, OUT
  • PUSH, POP
  • SER - samé 1 do registru
  • BRxx, SBIC, SBIS, SBRC, SBRS, CPSE

Prakticky odděleně je ve stavovém registru nastavován flag T - mění ho pouze instrukce BST, SET a CLT, které naopak nemění jiné příznaky. Lze jej tedy použít k větvení programu celkem nezávisle na jiných souběžných testech a větveních.

[editovat] Instrukce pracující v adresovém prostoru RAM

  • LD a ST s adresováním registry X, Y a Z pracují s RAM, a to vnitřní i vnější
  • podobně i LDD a STD (zde je adresa Y+q či Z+q, kde q je od 0 do 63)
  • LDS a STS mají 16-i bitovou adresu RAM přímo v kódu instrukce
  • PUSH, POP, RCALL, ICALL, RET, RETI atp. používají zásobník, který je (s výjimkou nejjednodušších AVR) v RAM

V adresovém prostoru RAM jsou kromě paměti RAM na určitých adresách i registry r0 až r31 a všechny I/O registry (prvních 64 z nich je přístupných i v I/O prostoru instrukcemi IN a OUT, ale další nikoli). Je to také jediný adresový prostor, který může mít vyvedenu vnější sběrnici. Chceme-li tedy přes klasické sběrnice připojit periferie, musíme je vnějším zapojením namapovat do prostoru RAM. V jazyce C pak toto vše můžeme snadno ovládat pomocí ukazatelů.

[editovat] Instrukce pracující v adresovém prostoru FLASH

  • LPM a SPM jsou velmi speciální instrukce pro čtení a zápis paměti programu

Přímé ovládání prostoru FLASH v jazyce C je značně obskurní. Pokud použijeme inicializované proměnné, překladač za nás vše zařídí a počáteční hodnoty načte pomocí LPM do RAM. Pokud ale nechceme plýtvat pamětí RAM na konstanty, jsou nutné zvláštní triky.

[editovat] Instrukce pracující v prostoru I/O portů

  • IN a OUT ovládají prvních 64 I/0 registrů. Další jsou dostupné jen alternativní cestou přes prostor RAM (viz výše)
  • CBI a SBI nastavují bity I/O registrů, ale dokonce jen pro prvních 32 - pro další už je nutno použít IN a OUT, případně jen mapování v RAM
  • SBIC a SBIS obdobně umožňují podmíněné provedení instrukce dle bitů v prvních 32 I/O registrech

Prostor I/O také není u AVR vyveden pomocí klasických sběrnic (stejně bývá zaplněn vnitřními periferiemi).

Cokoli je v I/O prostoru na portu A, je v prostoru RAM na adrese A+32 (aby se před to vešly r0 až r31, které v I/O nejsou), nebo hexadecimálně A+0x20. V katalogu v Register Summary jsou pak obě čísla napsána třeba takto: $1B ($3B).

Celkově tedy dostupnost různých registrů různými instrukcemi přes různé prostory vypadá takto:

prostor RAM (LD, ST, ...)
celý I/O prostor (IN, OUT)
I/O bitově (CBI, SBI) ______________________ ______________________
r0......r31 věci jako DDRB, PORTB, PINB ...vnitřní RAM... ...vnější RAM(a vnější brány)...


[editovat] Další odkazy

Instrukční sada osmibitových mikrořadičů AVR na root.cz

Grafický přehled instrukcí AVR z domény ourdev.cn

Osobní nástroje