Základy programování mikropočítačů Větvení programu, cykly a pole
Posloupnost instrukcí Úvod Program může být vyjádřen pomocí 4 základních částí: Posloupnost instrukcí Větvení Cykly Podprogramy (moduly) Minulý program na součet byl jen posloupnost instrukcí V této lekci se budeme zabývat větvením a cykly
Základní pojmy Větvení programu: program pokračuje jednou z několika možných „cest“. Skok (branch, jump): je změna v sekvenčním vykonávání programu. Slouží k větvení programu. Cyklus: část programu se vykoná vícekrát v závislosti na splnění určité podmínky. Proměnná: Reprezentuje hodnotu. Je to místo v paměti pro uložení hodnoty. Pole: datová struktura, která sdružuje určitý počet prvků o stejné velikosti. Na další straně Algoritmus
Větvení programu - realizace Větvení programu je realizováno podmíněnými skoky START Splněna podmínka skoku? Start: Instrukce Instrukce Podmíněný skok na N1 … Nepodmíněný skok na N2 N1: Instrukce N2: Instrukce ... ne ano Červený blok Skok na N1 Skok na N2 Modrý blok Zelený blok KONEC
Instrukce pro větvení BEQ – Skok pokud je rovno BNE – Skok pokud není rovno BRA – Skok vždy BHI – Skok pokud je větší BLO – Skok pokud je menší BCC – Skok pokud je carry bit nulový BCS – Skok pokud je carry bit nastaven A další … Jak instrukce ví jestli skočit? (např. že bylo rovno) BCC, BCS, BEQ, BGE, BGT, BHI, BHS, BLE, BLO, BLS,BLT, BNE, BRA,BRSET, BRCLR
Větvení programu – princip Instrukce např. pro porovnání nastaví příznakový registr CCR Instrukce podmíněného skoku provede skok podle příslušného příznaku v CCR Příklad: LDA #5 CMP #5 BEQ hopsa ... hopsa: NOP Do registru A nahraje číslo 5 Porovná A s pamětí: (A) – (M), zde 5-5 = 0, proto nastaví příznak nuly (ZERO) v CCR Skok pokud je příznak nuly nastaven: (Z) = 1 zde je nastaven, proto skočí na „hopsa“
Program 1: porovnání dvou čísel Úkol: máme definována dvě čísla, c1 a c2. Do proměnné „vetsi“ uložte větší z nich. Instrukce pro porovnání: CMP = porovná obsah registru A a paměťové buňky (M) a aktualizuje příznakový registr (CCR). Nemění obsah reg. A ani buňky M. CMP: (A) – (M) Operandy nejsou změněny Z toho plyne: musíme nahrát jedno z čísel do registru A, pak jej můžeme porovnat s druhým číslem.
Program 1: porovnání čísel Vývojový diagram LDA c1 CMP c2 BHI Skok Začátek c1 > c2 ANO LDA c2 STA vetsi BRA Konec NE Ulož c2 do „vetsi“ Skok: STA vetsi Ulož c1 do „vetsi“ Konec: NOP Konec
Program 1: použité instrukce LDA – nahraje číslo uložené v paměti do registru A A <- (M) CMP – porovná obsah A s paměťovou buňkou (A) – (M) BHI – skočí na zadané návěští pokud číslo v akumulátoru A je větší než číslo v paměťové buňce M Skok pokud (C) | (Z) = 0 STA – uloží obsah A do paměti M <- (A) BRA – skočí vždy (bez podmínky) na zadané návěští Žádný test Direktiva: DS.B – rezervuje N bajtů paměti (místo RMB) BHI skočí pokud není nastaven ani Zero ani Carry příznak: Z | C = 0 Po CMP (A-M) to znamená: Jestliže v A je stejné číslo jako v M, příznak Zero bude nastaven, neskočí. Jestliže je v A větší číslo, výsledek A-M bude kladný, nebude nic nastaveno, skočí. Jestliže je v A menší číslo, výsledek A-M bude záporný, Carry bude nastaven, neskočí
Program: porovnání čísel Zadání jména a umístění projektu 1. Výběr programovacího jazyka 2. Volba jména projektu a jeho umístění 3. Nastavení potvrdíme kliknutím na „Další“
Program: porovnání čísel Výběr příslušného typu mikropočítače a připojení 1. Výběr cílového mikropočítače 2. Výběr připojení mikropočítače 3. Kliknutím na „Dokončit“ ukončíme průvodce
Program: porovnání čísel, zdrojový kód c1 DS.B 1 c2 DS.B 1 vetsi DS.B 1 MOV #3,c1 MOV #5,c2 LDA c1 CMP c2 BHI Skok LDA c2 STA vetsi BRA Konec Skok: Konec:
Program větvení: krokování Program sestavíme a spustíme v simulátoru Sestavení (Make) Ladění (Debug) V simulátoru tlačítkem „single step“ provádíme po řádcích Krokování (Single step) Výsledek se zadanými čísly: V proměnné „vetsi“ je číslo 5 (c2)
Program porovnání: změna hodnot c1 a c2 Tlačítkem Reset můžeme restartovat simulaci bez zavření simulátoru Reset target Po resetu odkrokujte až ZA INSTUKCE MOV! Poté poklepejte na proměnou c1 nebo c2 v okně Data a zadejte novou hodnotu Poklepáním lze změnit obsah proměnné Všimněte si jak se mění příznaky v registru CCR po provedení instrukce CMP pro různé hodnoty c1 a c2
Větvení programu: přehled variant větvení (C)=0 (C)|(Z)=0 (Z)=0 (Z)=1 Stav CCR lda c1 cmp c2 beq skok c1=c2 bhs skok c1≥c2 bhi skok c1>c2 bne skok c1≠c2 Ukázka kódu Podmínka skoku
Větvení programu: přehled variant větvení – pokračování (C)|(Z)=1 (C)=1 Stav CCR lda c1 cmp c2 blo skok c1<c2 bls skok c1≤c2 Ukázka kódu Podmínka skoku
Větvení programu: samostatná práce Máme nadefinovány 3 proměnné c1, c2 a c3, každou o velikosti 1 byte. Vytvořte program, který v nich nalezne maximální číselnou hodnotu a uloží ji do proměnné cmax. Předtím než začnete vytvářet program, zakreslete na papír vývojový diagram představující algoritmus řešící daný úkol. Upravte program ze zadání č.1 tak, aby vyhledal minimální hodnotu a uložil ji do proměnné cmin.
Cyklus Cyklus = opakování určitého bloku kódu tak dlouho, dokud není splněna určitá podmínka. Navesti: instrukce1 instrukce2 … instrukceN Podmíněný Skok na “Navesti“ Instrukce za cyklem Realizace (jedna z možností): Návěští na začátku opakovaného bloku Na konci bloku test podmínky pro ukončení cyklu a podmíněný skok na začátek cyklu pokud není splněna podmínka pro ukončení cyklu Po splnění podmínky program opouští smyčku a pokračuje dále Podmínkou může být např. provedení cyklu N-krát. Cyklus se využije např. při práci s poli
Proměnné a pole Proměnná = „schránka“ pro uložení hodnoty. Pole = více schránek se společným jménem, jednotlivé prvky jsou přístupné přes jméno pole a index (celé číslo označující pořadí prvku). Adresy v paměti Proměnná c1 $81 $82 $83 $84 $85 $80 P(0) P(1) P(4) P(2) P(3) Pole P SECTION (SHORT) = Direktiva definující sekci kódu. První direktiva pro každou sekci nastaví location counter na nulu, další použití direktivy SECTION pro stejnou sekci nastaví location counter na adresu následující za koncem předchozí části této sekce. SHORT -> section bude v "zero page" tj v prvních 256 B RAM, kde je rychlejší přístup. Zde jsou na začátku registry (I/O porty) a pak od 0x80 do 0xFF je RAM. Pozn: Section pojmenovaná MY_ZEROPAGE je umístěna pak v paměti mikropočítače viz soubor PROJECT.PRM, jak je to ale s vlastními section, kam budou umístěny? --> Sekce může být v PRM souboru a pokud není, pak je umístěna na default rom nebo ram podle toho jestli obsahuje instrukce -> je považována za kod, nebo jen konstanty nebo proměnné. To je případ sekce MyCode, která nemá nikde definováno umístění a je umístěna do DEFAULT_ROM (protože obsahuje kod). P(n) = n-tý prvek pole P Jestliže adresa začátku pole je $81, pak n-tý prvek je na adrese: $81 + n K čemu je dobré pole? např. v programu pro ukládání teploty každou minutu, nemusíme pro každou hodnotu vytvářet proměnnou se jménem...
Indexové adresování ...Pojem potřebný pro práci s poli Princip: V registru procesoru H:X (tzv. indexový registr) je adresa začátku pole Instrukce pro práci s prvkem pole mají jako operand obsah index registru Inkrementací obsahu registru se mění aktuální prvek pole $81 $82 $83 $84 $85 $80 P(0) P(1) P(4) P(2) P(3) Pole P V H:X bude $81 Nuluje byte na adrese, která je v H:X tj. na adr. $81 Příklad: LDHX #P loop: CLR ,X AIX #1 BRA loop Inkrementuje H:X, příště CLR vynuluje byte na adr. $82
Program 2: nulování pole Úkol: Definujte pole M o velikosti 5 byte. Vynulujte prvky tohoto pole. Instrukce pro nulování: CLR = vynuluje byte paměti na zadané adrese. CLR: M <- $00 Postup: Opakujeme instrukci CLR a zvyšujeme obsah indexového registru H:X
Program 2: vývojový diagram Začátek LDHX #M ; Do registru H:X načteme ; adresu začátku pole LDA #0 ; Inicializujeme počitadlo ; cyklů Nastav indexový registr na začátek pole a inicializuj počitadlo cyklů opakuj CLR ,X ; Nuluj aktuální prvek pole ; jehož adresa je obsažena v ; indexovém registru H:X Zpracuj aktuální prvek AIX #1 ; Zvětšíme obsah indexového ; registru o 1. Tím se posuneme ; na další prvek pole INCA ; inkrementace počitadla cyklů Posuň na další prvek Zpracováno 5 prvků? NE CMP #5 ; porovnáme obsah počitadla ; cyklů s hodnotou 5 BLO opakuj ; pokud je menší jak 5, skoč na ; návěští opakuj. ANO Konec
Program 2: zdrojový kód M DS.B 5 LDHX #M LDA #0 opakuj: CLR ,X AIX #1 INCA CMP #5 BLO opakuj
Program 2: krokování V registru A je počitadlo průchodů cyklem V registru H:X se zvětšuje adresa aktuálního prvku Prvky pole jsou postupně nulovány
Obecné struktury smyček Smyčka s testem na začátku podmínka Tělo cyklu ANO NE Odpovídá cyklu while z C jazyka: while (podmínka) { příkaz_1; příkaz_2; … příkaz_n; } Cyklus s testem na začátku v případě nesplněné podmínky neproběhne ani jednou
Obecné struktury smyček Smyčka s testem na konci Odpovídá cyklu do z C jazyka: do { příkaz_1; příkaz_2; … příkaz_n; } while (podmínka) Tělo cyklu ANO podmínka NE Cyklus s testem na konci proběhne vždy minimálně jednou
Cykly: samostatná práce Vytvořte program, který v 5 prvkovém poli data o velikosti prvku 1 byte vyhledá maximální prvek a uloží jej do proměnné dmax. Předtím než začnete vytvářet program, zakreslete na papír vývojový diagram představující algoritmus řešící daný úkol. Modifikujte program tak, aby vyhledával minimální prvek pole. Pro jeho uložení zvolte proměnnou dmin.
Konec Úspěšně jste zvládli podmínky a smyčky v jazyce symbolických adres pro HCS08! Definice a vysvětlení základních pojmů viz např.: http://cs.wikipedia.org/wiki