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 | c |
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 | ||||||||||
|
|
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.