Nacitanie sestnastkoveho cisla

   V tejto lekcii sa budeme zaoberat podobnou rutinkou ako v predchadzajucej, avsak tentoraz cislo ulozene ako postupnost cifier v buffei nebude desiatkove, ale sestnastkove. Najprv sa pozrime na domacu ulohu z predchadzajucej lekcie.

   Jednotlive cifry nasho cisla sme mali v pameti ulozene ako obycajne znaky v kode ASCII. Ked si pozorne vsimneme hodnoty tychto kodov, uvidime ze kod kazdej cifry je presne o 48 vecsi ako hodnota, ktoru predstavuje tato cifra. Teda staci od kodu znaku odpocitat cislo 48 (ASCII kod znaku 0) a dostaneme hodnotu cifry.

   Jednym z podproblemov nasho programu bolo vynasobit aktualnu hodnotu cisla desiatimi. Najpohodlnejsie riesenie by bolo vyuzit uz hotovu rutinku na vynasobenie dvoch cisel z 4. lekcie. Lenze tato rutinka nasobi iba osembitove cisla. Dalo by sa to obist tak, ze by sme si zaciatok rutinky upravili tak, aby jeden operand bol v celom registri DE, do registra A vlozili cislo 10 a do registra HL poctivo vlozili nulu (lebo D uz nemusi byt nulove). Ja som vam vsak ponukol principialne ine a v danej situacii efektivnejsie riesenie. Pokial nasobime hodnotu v registri dakym malym vopred znamym cislom potom existuje efektivnejsi sposob, ako to spravit. Co keby sme skusili spravit toto: Register HL vynasobme dvomi (ADD HL,HL), potom si tento dvojnasobok niekam odlozme (napr. do BC), po odlozeni tento dvojnasobok este dvakrat vynasobme dvomi - tym dostaneme stvornasobok a osemnasobok. No a na zaver k tomuto osemnasobku pricitajme ten odlozeny dvojnasobok a dostavame... Ten kto hadal 10-nasobok mal uplnu pravdu.

   Prevod hexadecimalne zapisaneho cisla na jeho hodnotu je v niecom zlozitejsi, ale v niecom zase jednoduchsi. Kedze hexadecimalna sustava pouziva viac cifier ako desiatkova a navyse ich ASCII kody nenasleduju tesne za sebou (ako by sme si to zelali), bude urcovanie hodnoty jednotlivych cifier o nieco zlozitesie. Na druhej strane treba aktualnu hodnotu cisla nasobit sestnastimi. Ako uz vieme, 16 je pekne okruhle cislo (vid 0. lekciu) ktore sa da vyjadrit ako stvrta mocnina dvojky. Preto ak chceme nejake cislo vynasobit sestnastimi, staci ho len styri krat vynasobit dvomi. A prave v tomto je to jednoduchsie.

   Este pred tvorbou samotnej rutinky si treba ujasnit, ako mame zapisane cislice nasho cisla v bufferi (v nasom priklade mame cislo f4b3). Ucene povedane - musime si presne definovat vstupne udaje. Nech je nase cislo napisane ako postupnost hexadecimalnych cislic v obvyklom poradi (vyssie rady na nizsej adrese) a zakoncene lubovolnym znakom, ktory nezodpoveda ziadnej hexadecimalej cislici (v nasom priklade je tam medzera). Hexadecimalne cislice budeme kodovat tak, ako je to zauzivane - t.j. znakmi 0 az 9 a a az f (budeme pouzivat male pismena).

   Teraz nam uz nic nebrani aby sme mohli navrhnut nas program, ktory bude pouzivat taky isty postup ako program z minulej 6. lekcie - t.j. bude postupne nacitavat cifry, urcovat ich hodnoty a postupne pocitat aktualnu hodnotu cisla.

   Pri prepocte ASCII kodu znaku na hodnotu cifry sa na chvilku zastavme. Kody vsetkych hexadecimalnych cifier nelezia hned za sebou, ako je to pri desiatkovych cifrach - preto to uz nemozme mechanicky prepocitavat tak ako predtym. Pokial sa jedna o cifry 0 az 9, je vsetko v poriadku. Ale co s pismenami a az f ? Vsimnime si, ze ASCII kody tychto pismen tiez lezia bezprostredne za sebou, takze staci od kodu pismena odcitat urcitu konstatnu hodnotu a problem je vyrieseny. No nie celkom. Totiz na nasu smolu tato konstanta je ina ako pre cislice 0 az 9 ! V tejto situacii nam neostava nic ine ako otestovat, ze o aku cifru sa jedna (cislo alebo pismeno ?) a podla toho zvolit prislusnu konstantu, ktoru potom odcitame.

buffer db 'f4b3 ' Priklad nejakeho cisla 
    
hxbn ld de,buffer DE bude ukazovatel do buffera 
 ld hl,#00 HL bude obsahovat okamzitu hodnotu cisla 
hexa ld a,(de) prevzatie cifry z buffera 
 ld c,'0' Ak je jej ASCII kod mensi ako '0' 
 cp tak sa uz nejedna o ziadnu platnu cifru 
 ret a to znamena koniec cisla a navrat 
 cp '9'+1 Ak sa jedna o znaky '0'..'9' 
 jr c,cifra tak skok na odcitanie prisl. konstanty 
 ld c,'a'-10 Toto je konstanta pre znaky 'a'..'f' 
 cp 'a' Ak je kod znaku mensi ako 'a' 
 ret tak sa nejedna o cifru a navrat 
 cp 'f'+1 Ak je kod vecsi ako 'f' 
 ret nc tak to tiez nebude ziadna cifra 
cifra sub odcitanie prislusnej konstanty 
 inc de ukazovatel buffera na dalsi znak 
 add hl,hl 
 add hl,hl  \  Vynasobenie aktualnej 
 add hl,hl  /  hodnoty sestnastimi 
 add hl,hl 
 ld c,a pricitanie hodnoty 
 ld b,#00 cifry k samotnej 
 add hl,bc hodnote cisla 
 jr hexa a znovu pre dalsiu cifru 

   Dnes bude domaca uloha mozno trochu tazsia ako obycajne. Skuste sa zamysliet nad problemom presne opacnym - to znamena, ze mate v registri nejake cislo a chcete ho vypisat - cize previest na postupnost cislic a tuto postupnost cislic umiestnit do nejakeho buffera.

Vas Busy.

Nazad / back , predchadzajuca a dalsia lekcia