Nasobenie dvoch cisel

   Predpokladam, ze domacu ulohu z minulej lekcie sa vam bez problemov podarilo vyriesit. Uloha znela: Preco je "ZLO" mensie ako "zlo" ?
   Riesenie je este jednoduchsie ako samotna uloha. Vsimnite si, ze ASCII kody malych pismen maju vyssie hodnoty ako ASCII kody velkych pismen. Nas porovnavaci program porovnaval slova tak, ze porovnaval ASCII kody jednotlivych pismen. Prve pismeno "z" slova "zlo" ma kod #7A a prve pismeno slova "ZLO" ma kod #5A. Nas program porovnal najprv prve bajty retazcov - cize #7A a #5A. Zistil nezhodu a preto sa hned vratil s tym, ze retazec zacinajuci na #7A je "vecsi". Tym nam vlastne nepriamo ukazal, ze "zlo" je vecsie ako "ZLO".

   Ked sa dobre pozrieme na instrukcny subor Z80 uvidime, ze obsahuje plno roznych instrukcii na scitanie a odcitanie. Lenze v matematike existuje este cely rad dalsich operacii: nasobenie, delenie, umocnovanie, goniometricke funkcie, derivacie, integraly a mnohe ine... S integralmi sa (zatial) zaoberat nebudeme, lebo to by bolo (zatial) nad nase sily.
   Ale skusme si naprogramovat take nasobenie. To je operacia, ktoru pravdepodobne budeme po scitani a odcitani najcastejsie potrebovat.
   Vsimnime si najprv matematicku definicu nasobenia. Vynasobit cislo M cislom N znamena to iste ako keby sme k nule N-krat pripocitali cislo M. Tolko definicia. Teraz si polozme otazku. Mozme tuto definiciu nejak vyuzit ? N-krat nieco vykonat vieme (pouzijeme slucku) a pripocitavat tiez vieme, to znamena, ze tuto definiciu mozme priamo realizovat ! Takze podme na to.
   Zvolme si, ze budeme nasobit dve osembitove cisla v rozsahu 0 az 255. Tym sme si zaroven zvolili aj rozsah vysledku: najmensi vysledok bude nula (0*0), najvecsi bude 65025 (255*255). Cize vysledok bude 16-bitove cislo. Na to musime pametat pri vytvarani rutinky.
   Slucka, ktora zabezpeci opakovanie scitavania, musi vediet prebehnut aj nula-krat (ak N=0). Preto treba hned na zaciatku testovat, ci je N nulove. Ulozme si toto nase N do registra A (lebo ten sa najlahsie testuje na nulu). Po teste vykoname to pricitanie a slucku opakujeme N-1 krat. Opakovanie slucky N-1 krat sa nam najlepsie spravi tak, ze skocime znovu na zaciatok slucky s cislo N zmensenym o jednotku. Nasa slucka bude vyzerat takto:

 ld a,N 
slucka and 
 ret 
 (pricitanie) 
 dec 
 jr slucka 

   Vsimnime si sposob testovania akumulatora, ci je v nom nula. Deje sa to tak, ze sa vykona bitovy AND akumulatora so samym sebou. Vysledok bude teda ten isty ako povodny operand (nezmeni nam to akumulator), ale pre nas je dolezite, ze ked boli vsetky bity akumulatora nulove (to znamena N=0) tak sa nastavi zero a instrukcia RET Z vtedy ukonci nasu rutinku. Mohli by sme to testovat aj instrukciou CP #00, ale sposob pomocou AND A je rychlejsi a zabera o jeden bajt pamete menej.

   Podme teraz vyriesit to pricitanie. Ako sme uz zistili, vysledok by mal byt 16-bitovy. A hned sa nam ponuka instrukcia ADD HL,DE. Skusme ju dako vyuzit. Kedze vysledok tejto instrukcie je v registri HL, zvolme si, ze aj vysledok nasho programu bude v HL. No a neostava nam uz nic ine, len do registra DE vlozit cislo M. Najjednoduchsie by to slo spravit instrukciou LD DE,M - ale ma to hacik. Totiz operand tejto instrukcie je 16-bitovy, ale nasa hodnota M je iba osembitova.
   Tento hacik nas zatial nemusi trapit, pretoze asembler nam to prelozi tak, ze nizsi bajt, ktory sa zapise do E bude to nase M a vyssi bajt ktory pojde do D bude nula.
   Tym sme si vyriesili aj to pricitanie a mozme prikrocit k samotnej rutinke.
   HOP ! Na nieco sme ale zabudli. Vsimnime si este raz definiciu: "...ako keby sme K NULE n-krat..." Na zacatku musime regster HL vynulovat, aby tam nezostali dake "zbytky" z predchadzajucej cinnosti. Nulovanie by sme mohli urobit instrukciou LD HL,0 , ale mam pre vas riesenie, ktore je rychlejsie a zabera menej pameti. Co keby sme vyuzili tu nulu, ktora je v registri D a skusili ju vlozit do HL ? Kedze nemame instrukciu LD HL,D, musime pouzit dve instrukcie: LD H,D a LD L,D.
   Kompletny program na nasobenie bude vyzerat takto:

 ld de,M Cislo M (osembitove) 
 ld a,N Cislo N (osembitove) 
 ld h,d Vynulovanie HL 
 ld l,d  
slucka and Test A=0 ? 
 ret Ak ano tak koniec 
 add hl,de Ak nie tak pripocitaj 
 dec N-krat 
 jr slucka vykonavaj slucku. 

   Vysledok nasobenia bude ulozeny v registri HL.
   Ako uz byva nasim dobrym zvykom, nasleduje domaca uloha. Skuste podobnym sposobom realizovat rutinku, ktora bude delit dve cisla (16-bitove 8-bitovym). Pomocka: Robte to postupnym odcitanim a pouzite instrukciu SBC HL,DE.
   Uloha to nie je lahka (ale ani tazka) a asi budete musiet trosku popremyslat, ale ja verim, ze na to napokon pridete.

Vas Busy.

Nazad / back , predchadzajuca a dalsia lekcia