UNIVERZITA TOMÁŠE BATI VE ZLÍNĚ FAKULTA APLIKOVANÉ INFORMATIKY
PROGRAMOVÁNÍ MIKROPOČÍTAČŮ CVIČENÍ 1 První program v jazyce symbolických adres Jan Dolinay Petr Dostálek Zlín 2013
Tento studijní materiál vznikl za finanční podpory Evropského sociálního fondu (ESF) a rozpočtu České republiky v rámci řešení projektu: CZ.1.07/2.2.00/15.0463, MODERNIZACE VÝUKOVÝCH
MATERIÁLŮ A DIDAKTICKÝCH METOD
Cvičení 1 – První program v jazyce symbolických adres
Cvičení 1 – První program v jazyce symbolických adres
STRUČNÝ OBSAH CVIČENÍ:
Vysvětlení zadání – součet dvou čísel Nalezení a vysvětlení potřebných instrukcí Zapsání programu v prostředí Code Warrior Ladění programu Úkoly k procvičení
VSTUPNÍ ZNALOSTI: Toto cvičení předpokládá znalost principů, jak funguje mikropočítač a jak se tvoří programové vybavení pro něj.
CÍL:
Cílem cvičení je seznámit se se základními principy programování mikropočítačů v jazyce assembler a získat praktické zkušenosti s tímto programováním. Dalším cílem je naučit se vyhledávat informace v originální dokumentaci k používanému mikropočítači.
Cvičení se vztahuje k těmto otázkám
Instrukce a formáty instrukcí Základní principy a pravidla asembleru - tvar zdrojového řádku Typy operandů a jejich zápis, jména používaná v asembleru
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
2
Cvičení 1 – První program v jazyce symbolických adres
1. Řešené příklady Na cvičeních využíváme vývojový kit M68EVB908GB60 s mikropočítačem z rodiny HCS08. Programovat budeme v jazyce symbolických adres, assembleru. Zdrojový kód zde uváděných příkladů bude tedy v assembleru pro procesor HCS08. Pokud bychom chtěli napsat program pro jiný procesor (např. od firmy Atmel nebo Intel), instrukce by byly jiné, nicméně princip programování v assembleru je stejný.
Příklad 1: Součet dvou čísel Úkol: Sečíst dvě čísla uložená v paměti mikropočítače a výsledek součtu uložit do paměti. Jak víme z přednášky, procesor je schopen provést jen určité elementární operace – instrukce. Pokud potřebujeme, aby provedl cokoliv složitějšího, musíte to vyjádřit jako posloupnost těchto elementárních operací. V tom je podstata programování. Z omezeného počtu instrukcí, které procesor dokáže vykonat, musíme vytvořit takovou jejich posloupnost (program), která vykoná to, co potřebuje. V našem případě máme vytvořit posloupnost instrukcí, která provede součet dvou čísel. Lze oprávněně předpokládat, že procesor bude umět sečíst dvě čísla. Problém ale může být v tom, jak zadáme tato čísla a kam bude uložen výsledek. Podívejme se do instrukční sady pro náš procesor (HCS08). Přehled instrukcí najdeme v manuálu (data sheet) od výrobce mikropočítače, v případě HCS08 je přehled instrukcí součástí kapitoly CPU. Najdeme zde instrukci ADD, viz obr. 1.
Obr. 1 – část tabulky instrukcí z dokumentace k mikropočítači HCS08 [1]
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
3
Cvičení 1 – První program v jazyce symbolických adres
Ve sloupci „Description“ je symbolicky zapsáno jak instrukce funguje: A <- (A) + (M). To znamená, že se sečte obsah registru A, a obsah paměťové buňky (symbolicky označena jako M) a výsledek se uloží do registru A. Tedy obsah registru A se po provedení součtu přepíše jeho výsledkem. Z principu fingování instrukce plyne, že musíme nejprve jedno z čísel připravit do registru A, pak můžeme pomocí instrukce ADD přičíst druhé číslo, a protože výsledek bude v registru A, a my jej chceme mít uložen v paměti, budeme muset ještě uložit obsah registru A do paměti. Pokud by existovala instrukce na sečtení dvou čísel přímo v paměti, která by výsledek také uložila do paměti, bylo by to jednoduché – celý program by byl tvořen jedinou instrukcí. S ohledem na dostupné instrukce procesoru HCS08 musíme ale použít instrukce tři - tři elementární operace. Posloupnost příkazů pro procesor tedy bude slovně zapsána takto:*
Nahraj do registru A první z čísel Proveď součet (pomocí instrukce ADD) s druhým z čísel Obsah registru A (tj. výsledek) ulož do paměti
* Tento zápis je pro srozumitelnost zjednodušen. Nikde neurčujeme obě čísla (operandy) ani místo pro uložení výsledku. Ve skutečném programu musí být uvedeny adresy paměťových buněk, ve kterých jsou operandy a výsledky uloženy.
V instrukční sadě vyhledáme zbývající dvě instrukce pro načtení čísla z paměti do registru A, a pro uložení obsahu registru A do paměti. Najdeme instrukce LDA (load accumulator A) a STA (Store Accumulator A). Pro zápis algoritmu můžeme také použit vývojový diagram, viz obr. 2.
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
4
Cvičení 1 – První program v jazyce symbolických adres
Obr. 2 – Vývojový diagram pro součet dvou čísel instrukcemi procesoru HCS08
Na obrázku je uveden také zápis odpovídajících instrukcí k jednotlivým operacím. Všimněte si, že kromě samotných instrukcí je nutno uvést také určité upřesňující informace, operandy. Např. pro instrukci LDA tj. načtení dat do registru A je nutno uvést, co se má vlastně do registru A načíst. Podobně u instrukce ADD je pouze jeden operand určen přímo definicí instrukce (sečte se obsah registru A s…). Druhý operand, číslo, které se má sečíst s obsahem registru A, je nutno uvést. Na úrovni procesoru bychom v případě čísel uložených v paměti museli jako parametry uvést jejich adresu. Využijeme ale výhod assembleru a místo číselné hodnoty (adresy) přiřadíme jednotlivým paměťovým buňkám jména. Zde využíváme tři paměťová místa: dva sčítance a výsledek. Pojmenovali jsme je cislo1, cislo2 a vysledek. Konkrétní číselné hodnoty do proměnných cislo1 a cislo2 uložíme podle uvážení, protože v zadání nejsou uvedeny. Např. zvolme cislo1 = 2 a cislo2 = 5. Skutečný užitečný program by pravděpodobně tyto hodnoty získával od uživatele, tak aby tento mohl zadat čísla, která si přeje sečíst a dozvěděl se výsledek. Interakci programu s uživatelem ovšem budeme řešit až později takže čísla zvolíme napevno v programu a výsledek zkontrolujeme přímo „nahlédnutím“ do paměti mikropočítače pomocí ladícího nástroje (debuggeru).
Jak zapsat program? V první řadě potřebujeme vědět, jakým způsobem se program zapíše a jak se dostane do mikropočítače. Program se zapisuje do prostého textového souboru s příponou ASM. Poté se přeloží pomocí překladače a vznikne binární tvar programu (v případě HCS08 s příponou .S19). Tento binární tvar se pak přenese do mikropočítače pomocí sériové linky. Na straně mikropočítače k tomu MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
5
Cvičení 1 – První program v jazyce symbolických adres
slouží jednoduchý „operační systém“, tzv. monitor. Monitor je program, který je umístěn v paměti ROM (resp. chráněné části paměti flash) a umožňuje provádět s mikropočítačem základní operace jako je nahrávání a spouštění uživatelských (vašich) programů. Celý postup od napsání programu do jeho spuštění na mikropočítači se dříve prováděl pomocí jednotlivých programů asi takto. V textovém editoru jste napsali program. Z příkazového řádku jste spustili překladač, který váš program přeložil do strojového kódu, resp. do formátu pro přenos do mikropočítače. Pak jste pomocí terminálu (program pro komunikaci po sériové lince) zadali monitoru v mikropočítači příkaz k přijetí programu a program jste pomocí terminálu po sériové lince nahráli do paměti mikropočítače. Poté jste pomocí příkazu monitoru program spustili. Moderní metoda využívá tzv. integrovaných vývojových prostředí (IDE), které všechny tyto činnosti spojují. Zdrojový kód tedy napíšete v textovém editoru který je součástí IDE. Pomocí tlačítka jej pak přeložíte a nahrajete do mikropočítače. Ladící program (debugger) vám pak umožní program v mikropočítači spustit nebo i krokovat po jednotlivých instrukcích a prohlížet si obsah paměti a registrů procesoru. S prací s IDE se seznámíme při tvorbě prvního programu. V assembleru platí, že každá instrukce se zapisuje na nový řádek. Obecná struktura řádku programu v jazyce assembler vypadá následovně: Návěští
instrukce
operandy
komentář
Řádek se tedy skládá ze čtyř částí. Návěští – pojmenovává určité místo v programu. Používá se jestliže se na toto místo chceme odvolat z jiné části programu, např. pokud sem bude směřovat skok. Také jména proměnných se zapisují v poloze na řádku stejné jako návěští. Instrukce – je zkratka operace, která se má provést. Operandy – jsou případné parametry, které instrukce vyžaduje ke své činnosti. Komentář – je textová poznámka, např. popisující co daný řádek dělá a proč. Pusťme se tedy do programování… Budeme používat vývojové prostředí CodeWarrior (IDE), které umožňuje vyvíjet programy pro širokou paletu mikropočítačů i jiných platforem včetně HCS08. I když se možná v budoucnu setkáte s jiným vývojovým prostředím, základní principy jsou u všech IDE stejné.
Spusťte prostředí Code Warrior for HC08. Z nabídky zvolte vytvoření nového projektu (Create New Project) MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
6
Cvičení 1 – První program v jazyce symbolických adres
7
Krok 1 – Vytvoření projektu Před vytvořením programu musíme ve vývojovém prostředí vytvořit projekt. Projekt je v podstatě skupina souborů, které spolu tvoří program. V nejjednodušším případě je program tvořen jediným souborem – zdrojovým kódem v assembleru U moderních vývojových prostředí se ale využívají další pomocné soubory jako jsou soubory definic symbolů a konfigurační nastavení. Proto moderní IDE vyžadují aby zdrojový kód byl součástí nějakého projektu. V našem případě v prvním kroku průvodce vytvořením projektu musíme zadat jméno projektu (např. soucet), dále složku kam bude projektu umístěn a použitý programovací jazyk (assembler).
Obr. 3 – Vytvoření projektu v CodeWarrior
CodeWarrior vytvoří ve vybrané složce podsložku stejného jména jako je projekt. Zdrojový kód programu, který budeme psát bude umístěn v podsložce Source ve složce projektu a bude se jmenovat MAIN.ASM.
Krok 2 - výběr mikropočítače a připojení Dalším krokem při vytváření nového projektu je výběr konkrétního typu mikropočítače, pro který chceme psát program. Rodina mikropočítačů HC08 obsahuje mnoho členů (tzv. derivatives), které se mohou lišit dostupnými porty apod. a proto Code Warrior vyžaduje specifikaci pro který typ má program vytvořit. V našem jednoduchém příkladu není toto důležité, ale s ohledem na budoucí programy, které už budeme spouštět na skutečném MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
Cvičení 1 – První program v jazyce symbolických adres
mikropočítači vybereme typ mikropočítače, který budeme využívat a to MC9S08GB60. Toto kompletní označení mikropočítače vypadá složitě, ale pro praktické použití postačí, když budete vědět, že typ mikropočítače, který používáme je GB60. Připojení je způsob propojení mezi vývojovým prostředím a mikropočítačem. Typické je propojení přes sériovou linku. V našem případě ale nebudeme výsledný program nahrávat do mikropočítače nýbrž jej vyzkoušíme pouze v softwarovém simulátoru, takže zvolíme propojení Full chip simulation.
Obr. 4 – Výběr typu mikropočítače a připojení
Zápis kódu programu Tímto je průvodce novým projektem dokončen a po kliknutí na tlačítko Dokončit se nám otevře okno vývojového prostředí i s právě vytvořeným projektem a zdrojovým kódem programu. Code Warrior už opravdu vygeneroval nějaký kód do zdrojového souboru MAIN.ASM. Tento kód představuje kostru aplikace, která sice nic nedělá, ale obsahuje už základní inicializaci a potřebné definice. Tímto způsobem nám vývojové prostředí šetří práci – nemusíme psát kód, který je nutný (a opakuje se) v každém programu. Dopište do této kostry následující dva bloky kódu. Pozor na jejich správné umístění. První blok, data programu, musí být za definicí MY_ZEROPAGE SECTION SHORT a druhý blok, kód programu, pak za návěštím MainLoop v sekcí kódu. ;Blok 1 cislo1 cislo2 vysledek
RMB RMB RMB
1 2 1 MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
8
Cvičení 1 – První program v jazyce symbolických adres ;Blok 2 MOV MOV
#2, cislo1 #5, cislo2
LDA ADD STA
cislo1 cislo2 vysledek
Obr. 5 zachycuje výsledný stav. Srovnejte zapsaný kód s vývojovým diagramem výše.
Obr. 5 – Výsledný vzhled zdrojového kódu. Žluté bloky je kód který jsme dopsali.
Vysvětlení programu V prvním, horním bloku kódu definujeme tři proměnné. Každou o velikosti jeden bajt. K tomu používáme direktivu RMB (reserve memory byte = rezervuj bajt paměti). MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
9
Cvičení 1 – První program v jazyce symbolických adres
Zápisem cislo1 RMB 1 říkáme překladači, že má vyhradit 1 bajt paměti, na který se budeme v programu odkazovat symbolickým jménem cislo1. Skutečné umístění (adresa) tohoto byte v paměti pro nás není důležitá. V druhém bloku pak nejprve do proměnných cislo1 a cislo2 nahrajeme nějaké hodnoty, abychom mohli program vyzkoušet. V tomto případě do proměnné cislo1 nahráváme hodnotu 2 a do cislo2 nahráváme 5. Celý kód až dosud je tedy jakási „provozní režie“ - museli jsme překladač informovat jaké proměnné hodláme používat (definovali jsme proměnné) a museli jsme do těchto proměnných přiřadit nějaké konkrétní hodnoty abychom program mohli vyzkoušet. Další část kódu už provádí požadovaný součet. Tento kód už jsme vysvětlili u vývojového diagramu. Protože instrukce pro součet, ADD, sčítá registr A s pamětí, musíme nejprve nahrát jedno z čísel do registru A. K tomu slouží instrukce LDA. Pak můžeme přičíst druhé číslo – ADD cislo2. A protože výsledek je v registru A, a my jej máme uložit do paměti, následuje instrukce STA, která uloží obsah registru A do proměnné výsledek. Všimněte si, že u instrukcí a direktiv nezáleží na tom, zda je píšeme velkým nebo malým písmem, např. RMB nebo rmb je totéž. Navíc CodeWarrior instrukce barevně zvýrazňuje, což slouží jako pomůcka - ihned vidíme, že instrukce je napsána správně.
Překlad programu Jakmile máte program napsaný, zkuste jej přeložit pomocí tlačítka Make, viz obrázek níže. Pokud jste při zápisu kódu neudělali chybu, měl by překlad proběhnout úspěšně. V CodeWarrior se to projeví tak, že se neobjeví okno se seznamem chyb. Pokud naopak váš zdrojový kód obsahuje chyby, objeví se okno s vyznačenými řádky, na kterých našel překladač ve vašem kódu chybu i její popis. Nejčastější chyby: názvy proměnných (cislo1, cislo2 a vysledek) nezačínají od levého okraje stránky, tj. je před nimi mezera nebo několik mezer, což není v assembleru pro HC08 dovoleno. Nedodrženo použití velkých/malých písmen v názvu proměnných, např. U instrukce LDA je napsáno „cislo1“ (malým písmem) ale nahoře je definováno jako Cislo1, tj. první písmeno názvu je velké. Nedodržení umístění programu do sekcí data a kód – podle obrázku.
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
10
Cvičení 1 – První program v jazyce symbolických adres
Ladění programu Jestliže máme program přeložen, můžeme přistoupit k jeho ladění. V angličtině se pro tuto činnost používá trefného označení debugging, tedy „odchybování“, nebo i „odblešení“ (bug = brouk; v počítačové terminologii chyba). Spusťte program v simulátoru stiskem příslušného tlačítka na panelu nástrojů v prostředí CodeWarrior, viz obrázek.
Obr. 6 – Tlačítka pro sestavení a ladění na panelu nástrojů v CodeWarrior
Objeví se nové okno, které si nejprve popíšeme. Jedná se o okno simulátoru, viz obrázek.
Obr. 7 – Okno simulátoru a debuggeru
V okně Source (Zdrojový kód) vidíme kód laděného programu – momentálně jsou tam instrukce, které vygeneroval CodeWarrior, ale když se v tomto okně posunete níže, uvidíte svůj kód. Pod oknem source je okno Data, v němž se zobrazují proměnné programu – cislo1, cislo2 a vysledek. Napravo nahoře je okno Assembly, které zobrazuje, jak kód programu vypadá v paměti. To pro nás momentálně není zajímavé. Zajímavější je okno pod ním, MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
11
Cvičení 1 – První program v jazyce symbolických adres
Register. Zde je vidět obsah registrů procesoru, tj. registrů A, H, X a dalších. Úplně dole vpravo je pak okno Memory (paměť) zobrazující obsah paměti mikropočítače. Krokujte nyní program tlačítkem Single step. Tím se program provádí po jednotlivých instrukcích. Odkrokujte nejprve za instrukce MOV a všimněte si, že v okně Data v proměnných cislo1 a cislo2 se objeví čísla 2 a 5. Pomocí instrukcí MOV jsme si do proměnných přesunuli tato dvě čísla, abychom program mohli vyzkoušet. V proměnné vysledek je stále nedefinovaná hodnota (undefined...), viz obrázek.
Obr. 8 – Krokování programu
Nyní odkrokujte dále až na konec programu a přesvědčte se, že v proměnné vysledek se objeví číslo 7, tedy součet čísel 2 a 5, viz obrázek.
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
12
Cvičení 1 – První program v jazyce symbolických adres
Obr. 9 – Krokování programu
Tím náš kód končí a program se dostává do smyčky vygenerované vývojovým prostředím, která slouží k resetování obvodu watchdog (hlídacího psa). Význam této smyčky si vysvětlíme později. Okno simulátoru můžete nyní zavřít, čímž se vrátíte zpět do vývojového prostředí Code Warrior. Spusťte nyní simulátor znovu tlačítkem Debug a tentokrát při krokování sledujte obsah registru A. Po instrukcí LDA cislo1 by se v něm měl objevit obsah proměnné cislo1 tj. 2. Po instrukci ADD se přičte 5 a výsledek se uloží do A, tj. v reg. A bychom měli vidět číslo 7. Po uložení instrukcí STA vysledek se v proměnné vysledek objeví toto číslo také, přitom v registru A zůstane zachováno.
1. Příklady k procvičení 1. Upravte program tak, aby vyřešil zadání: vysledek = cislo2 – cislo1. 2. Upravte program tak, aby místo sčítání prováděl násobení cislo1 * cislo2. 3. Naprogramujte řešení výrazu: vysledek = [ (cislo1 + cislo2) – (cislo3 + cislo4) ] * cislo5.
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
13
Cvičení 1 – První program v jazyce symbolických adres
Poznámka: Hodnoty v úkolu 3 zvolte takto: cislo3 = 3, cislo4 = 1 a cislo5 = 9. Pak by výsledek měl být 27. Do programu musíme dodefinovat proměnné cislo3 až cislo5 a případně také několik pomocných proměnných, které budete potřebovat. Pojmenujeme je např. pom1, pom2 atd.
Doplňující zdroje [1]
Freescale: Firemní dokumentace pro mikropočítače HCS08, dostupné online: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=S08GB&nodeId= 01624684491437EDD5
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
14