Digitális technika 2 - Házi második részére példa
A VIK Wikiből
Figyelem! A programot kizárólag azért töltöttem fel, hogy részleteiben esetleg ötleteket adhasson a házi feladat készítése közben, vagy még inkább annak megírása után esetleges referenciaként szolgálhasson. A programot akár csak részleteiben lemásolni és házi feladatként beadni szigorúan tilos, és veszélyes. Természetesen más az alábbitól eltérő megoldási módok is léteznek, és természetesen el is fogadják őket házifeladat-beadásban.
; BEMENET: ; DE: kezdőcím ; BC: hossz ; feltöltés: ~(hi^lo) (az alsó és felső címbájt kizáró vagykapcsolatának negáltja) ; ; KIMENET ; DE: legalacsonyab című hiba vagy kezdőcím ; HL: hibák száma ; Z = 1: volt hiba ELLENOR: ; A feladatkiírás szerinti rutin PUSH PSW ; Mentés PUSH B ; a darabszámra is szükség lesz később ; HL <- kezdőcím (ciklus előfeltétel) MOV H, D MOV L, E CIKLUS_FELTOLT: ; Feltöltő ciklus. HL mutat az aktuális címre. MOV A, B ; Ciklusfeltétel ellenőrzése ORA C ; BC = 0 ? JZ CIKLUS_FELTOLT_VEGE ; Kiszámítjuk a felső és alsó bájt kizáró vagy kapcsolatának negáltját MOV A, H XRA L ; A = H XOR L CMA ; A = ~A, negálás MOV M, A ; Kiírjuk a memóriába INX H ; Következő cím DCX B ; Egyel kevesebb cím van hátra JMP CIKLUS_FELTOLT CIKLUS_FELTOLT_VEGE: ; Ellenőrzés: ; A stackben tároljuk a legalacsonyabb hibacímet, a hibák számát pedig a DE regiszterben. POP B ; BC <- a memóriablokk hossza (visszaállítjuk a stackből az értéket) PUSH B ; De a stackben is ott hagyjuk PUSH D ; Elmentjük a memóriablokk kezdőcímét a stackbe. Az első hibánál felülírjuk majd. ; Innentől: SP <- kezdőcím / első hiba MOV H, D MOV L, E ; HL <- kezdőcím (ciklus előfeltétel) LXI D, 0 ; DE <- eddigi hibaszám ; Változók: DE hibaszám ; HL aktuális memóriacím ; BC maradék blokk hossza ; Stack: ; +-------------------------+ ; | E *kezdőcím / első hiba | <-- SP ; | D *kezdőcím / első hiba | ; | C eredeti hossz | ; | B eredeti hossz | ; | PSW (flags) | ; | PSW (A) | ; | ... | CIKLUS_ELL: ; Ellenőrzőciklus MOV A, B ; ciklusfeltétel ugyanaz, mint a feltöltéskor: hátralévő blokkhossz BC != 0 ORA C JZ CIKLUS_ELL_VEGE ; Ellenőrző kód kiszámítása MOV A, H XRA L CMA ; A = ~(H XOR L) ; Összevetés a memóriával. Ugyanaz -> A = 0, Z = 1 XRA M JZ ELL_FOLYT ; HIBA VAN (Z = 0) MOV A, D ORA E ; Ha nem volt még hiba, akkor A = DE = 0, Z = 1 JNZ VOLT_MAR_HIBA ; ELSŐ HIBA (Z = 1), mentsük el a helyét INX SP INX SP ; POP (kezdőcím) PUSH H ; SP <- első hiba címe VOLT_MAR_HIBA: INX D ; Hibaszám növelése ELL_FOLYT: ; Ciklus folytatása INX H ; következő memóriacím DCX B ; egyel kevesebb van hátra JMP CIKLUS_ELL CIKLUS_ELL_VEGE: ; ellenőrzés vége, visszatérés a kiírás szerint XCHG ; HL <- hibaszám, DE <- x POP D ; DE <- kezdőcím / első hiba címe (végleges kimenet) POP B ; stack ürítése, B visszaállítása, SP <- PSW (flagek) MOV A, H ORA L ; HL = hibaszám = 0 ? Z flaget állítja. XTHL ; L <- flagek, H <- A (PSW), SP <- HL (hibaszám) MOV A, L ; a flageket (Z-t) fogjuk állítani JZ NINCS_HIBA ; hibaszám = 0, Z = 1 volt ; VOLT HIBA ORI 64 ; 6. bit (Z) 1-be állítva (64 = 0100 0000) JMP VEGE NINCS_HIBA: ANI 191 ; 6. bit (Z) 0-ba állítva (191 = 1011 1111) VEGE: MOV L, A XTHL ; Stack <- PSW (Z felülírva), HL <- hibaszám (végleges kimenet) POP PSW ; flagek visszaállítva, Z felülírva (végleges kimenet) RET