Asembler – úvod
Porovnání s běžnými programovacími jazyky
V principu je programování v asembleru už klasické programování s následujícími rozdíly:
- Nejsou k dispozici pokročilejší konstrukce (smyčky, podmínky apod.), ale jen základní skok (v C ho znáte jako GOTO) a jeho podmíněná varianta.
- K dispozici máte 32 8bitových registrů r0-r31. Pracujte s nimi jako s 8bitovými proměnnými, které už nemusíte deklarovat.
- Program nemusí mít nutně žádný main ani něco jako begin a end. Pokud neřeknete jinak, tak prostě začne na prvním řádku a jede dál, dokud neprojede celý kód.
- Neexistují datové typy, pokud s něčím pracujete jako s ASCII znakem, desítkově, dvojkově, hexadecimálně, tak se při překladu nahradí výslednou hodnotou, ale procesor nic takového nezná. Jediná podpora je pro čísla bez znaménka a se znaménkem – tím, že zavoláte jinou instrukci.
Následující kód je plně funkční, postupně uloží do registrů tu samou hodnotu:
ldi r16, 'a'
ldi r17, 97
ldi r18, -159
ldi r19, 0x61
ldi r20, 0b01100001
ldi r21, 'b'-1 ; za strednikem je komentar
ldi r22, 2*48+1 ; prekladac spocita vysledek a ulozi primo konstantu
;ldi r23, r22+1 ; nelze, r22 neni konstanta - musi se pouzit instrukce na scitaniVybrané často používané instrukce
Stručný přehled instrukcí je k dispozici zde. Nezalekněte se první tabulky s vysvětlivkami. Některé vybrané základní instrukce, které se budou hodit nejčastěji (a jejich C přepis a vysvětlení):
ldi r16, 97 ; r16 = 97 // lomitka jsou tu pouze pro vas, asembler je nezna
add r16, r17 ; r16 = r16 + r17 // vzdy se uklada do prvniho v poradi
sub r16, r17 ; r16 = r16 - r17
and r16, r17 ; r16 = r16 & r17 // bitovy operator
ori r16, 42 ; r16 = r16 | 42 // bitovy operator s konstantou 1
inc r16 ; r16++
mov r16, r17 ; r16 = r17 // vytvori se kopie, v r17 hodnota zustava
jmp nekam ; goto nekam // <nekam> je navesti, tj. libovolny retezec ze "slusnych" znaku.
; Skoci se na radek, kde je napsane navesti <nekam:> (s dvojteckou).
call proc ; volani podprogramu se jmenem <proc> (<proc> je take navesti). Velmi podobne jako jmp,
; ale ulozi si adresu aktualni instrukce, takze je mozny navrat zpatky pomoci instrukce ret.
;ret ; navrat z podprogramu (za radek s poslednim call) - tady by nedaval smysl a hlasil by chybu
cp r16, r17 ; porovnej r16 a r17 (fakticky se provede odecteni r16 - r17 a
; zpravidla pak nasleduje podmineny skok)
breq jinam ; podmineny skok - podiva se na vysledek predchozi instrukce a skoci, kdyz je podminka splnena.
; V tomto pripade EQ, tj. rovnost - tak skoci na radek s navestim <jinam> 2
lsl r16 ; r16 = r16 * 2 // logicky posun o jedno misto doleva
nekam: ; sem skoci ten "jmp nekam" o par radku vyse
jinam: ; sem skoci ten "breq jinam" o par radku vyse
jmp PC ; skok na aktualni radek 3
proc: ; sem skoci ten "call proc" o par radku vyse
; tady bude obsah podprogramu
ret ; navrat z podprogramu (za radek posledniho call).
; Tady ma smysl a vrati se na radek za call, tj. na radek s "cp r16, r17",
; protoze predchozi radek s ";ret" je zakomentovany.- Některé aritmetické a logické instrukce mají variantu s i na konci názvu. Takové berou jako druhý parametr konstantu a lze je použít pouze na registry r16-r31, jinak pracují aritmetické a logické instrukce zpravidla se dvěma registry a lze je použít na všechny registry.
- Podmíněných skoků je více typů, liší se druhými dvěma písmeny v názvu a podmínkou, kterou vyhodnocují. Zpravidla následují po instrukci cp nebo cpi, ale není to nutné – většina instrukcí po sobě nastaví výsledek tak, aby se podmíněný skok mohl rozhodnout (např. za dec r16 může následovat breq nekam, který se podívá, zda byl výsledek dekrementace nula).
- PC je návěští, které automaticky ukazuje na aktuální řádek. jmp PC je de facto malá nekonečná smyčka, díky které program nepokračuje dál do kódu, který chceme používat jako podprogram proc.