Porovnavanie retazcov II.

   V tejto lekcii este ostaneme pri probleme porovnavania dvoch retazcov v pameti. A hned zacneme riesenim domacej ulohy.
   Uloha bola vhodne vyuzit v nasom programe instukciu cpi. Tak sa teda pozrime, co vlastne tato instukcia robi: Najprv porovna akumulator s bajtom na adrese ulozenej v registri HL (presne ako instrukcia cp (hl) v nasom programe), potom zvecsi HL o jednotku, BC zase zmensi o jednotku a nakoniec nam skontroluje, ci BC je nulove. Cize cpi nam plne nahradi tieto instrukcie:

cp (hl) 
inc hl 
dec bc 
ld a,b 
or 

   Lenze je tu jeden maly hacik. Vysledok porovnania cp sa uklada do priznakov ZERO a CARRY, ale nulovost BC sa neuklada do priznaku ZERO (ten je uz obsadeny) ale do priznaku P/V ! S tymto musime ratat vtedy, ked robime na konci slucky podmieneny skok. Tento skok uz nesmie testovat ZERO ale P/V. Relativny skok jr pe,... testujuci P/V neexistuje, prto budeme musiet pouzit absolutny skok jp pe,....
   Nas program bude potom (po druhom priblizeni) vyzerat takto:

 ld hl,add1 adresa prveho retazca 
 ld de,add2 adresa druheho retazca 
 ld bc,len dlzka retazcov 
loop ld a,(de) vezme bajt z druheho retazca 
 inc de a posunie jeho ukazovatel 
 cpi  cp (hl); inc hl;dec bc; bc=0 ? 
 ret nz ak su bajty rozne tak koniec 
 jp pe,loop ak je BC<>0 tak opakuj 
 ret  koniec pri zhodnych retazcoch 

   To, co sme vlastne urobili s programom pouzitim instukcie cpi sa odborne nazyva optimalizacia programu vzhladom na jeho dlzku. (Este existuje optimalizacia vzhladom na cas vykonavania, ale tou sa este nebudeme zaoberat.) Kym povodny program (uvedeny v druhej lekcii) mal 19 bajtov, tento program ma uz iba 18 bajtov a pritom robi presne to iste.
   No skuske ist este dalej. Co by sa stalo, keby sme "vymenili" posledne dve instukcie (samozrejme tak, aby program aj nadalej fungoval) ?

Namiesto tohto by bolo toto
jp pe,loop   
ret 
ret  po
jp loop

   Pred tym sme ostavali v slucke pokym bola parita parna (to znamena nenulove BC) a potom sme sa vratili pomocou ret. Teraz v slucke testujeme, ci je parita neparna (nulove BC) - ked je tak sa vratime pomocou ret po. Ak sa nahodou navrat nekonal (parna parita) tak nadalej ostavame v slucke. Cize vlastne v principe navonok robime v obidvoch pripadoch to iste.
   A teraz pride vysvetlenie preco sme to vlaste vymenili. Na konci nasej rutinky je absolutny nepodmieneny skok jp loop. Keby sme ho nahradili relativnym nepomienenym skokom, usetrime dalsi bajt v pameti, pretoze instrukcia relativneho skoku ma o jeden bajt menej. Tym sme nas program este viac zoptimalizovali vzhladom na dlzku v pameti - uz ma iba 17 bajtov (...a stale robi to iste).
   Nas program bude teda po poslednom tretom priblizeni vyzerat presne takto:

 ld hl,add1  
 ld de,add2  
 ld bc,len  
loop ld a,(de)  
 cpi   
 inc de  
 ret nz  
 ret po navrat ak je uz BC nulove 
 jr loop inak pokracovanie porovnavania 

   Na poradi instrukcii cpi a inc de vobec nezalezi, pretoze tieto instrukcie operuju na navzajom disjunktnych mnozinach udajov - povedane po slovensky, ze ich oblasti posobenia nemaju nic spolocne a preto sa ani navzajom nemozu ovplyvnovat. Instrukcia cpi pracuje nad registrami A,HL,BC a priznakmi, kym instrukcia inc de meni iba register DE.

   Na zaver je aj tentoraz pripravena pre vas mala domaca uloha: Majme niede v pameti pocitaca velkymi pismenami napisane slovo "ZLO". Nech je niekde na inom mieste v pameti napisane to iste slovo, ale tentoraz malymi pismenami: "zlo". Teraz si predstavme, ze tieto dve slova su dva retazce, ktore ideme porovnavat. To ze tieto dva retazce nebudu zhodne, nam je hned jasne, pretoze sa sice skladaju z tych istych pismen, ale v kode ASCII predstavuju tieto pismena rozne znaky.
   Ked pustime (tu by sa prefektne hodilo slovicko "postveme") nas program na tieto dve slova, naozaj zistime, ze tieto dve slova predstavuju rozne retazce. Ale tu nastava velmi zaujmavy paradox - zistujeme ze nas program oznacil slovo "zlo" napisane malymi pismenami za vecsie ako "ZLO" napisane velkymi pismenami !!! Preco je to tak ? A prave riesenie tohto paradoxu je ta domaca uloha.
   Vasa domaca uloha teda znie: Vysvetlite, preco nas program oznacil slovo "ZLO" pisane velkymi pismenami za mensie ako druhe slovo "zlo", ktore bolo pisane malymi pismenami.
   Uloha je to velmi lahka, ale keby sa vam ju nahodou nepodarilo vyriesit, nic to, v buducej lekcii bude spravne riesenie.

Vas Busy.

Nazad / back , predchadzajuca a dalsia lekcia