Ujemne indeksowanie
From Atariki
Wersja z dnia 14:47, 3 cze 2008 Xxl (Dyskusja | wkład) ← Previous diff |
Wersja z dnia 09:28, 11 kwi 2009 KMK (Dyskusja | wkład) (merge) Next diff → |
||
Linia 10: | Linia 10: | ||
BNE _DO | BNE _DO | ||
</pre> | </pre> | ||
+ | |||
+ | Operacje na wielu kolejnych bajtach, jak kopiowanie danych z miejsca na miejsce, dodawanie lub odejmowanie liczb wielobajtowych itd. dobrze jest w celu skrócenia programu zapętlić w podobny sposób. | ||
+ | |||
+ | Zwłaszcza arytmetyka jest często zapisywana w postaci "rozpętlonej", gdyż sterujący pętlą rozkaz CPX lub CPY zmienia znacznik C rejestru znaczników procesora kasując tym samym informację o przeniesieniu arytmetycznym. Łatwo się jednak tego problemu pozbyć. Zamiast: | ||
+ | |||
+ | <pre> | ||
+ | clc | ||
+ | lda aaa | ||
+ | adc bbb | ||
+ | sta ccc | ||
+ | lda aaa+1 | ||
+ | adc bbb+1 | ||
+ | sta ccc+1 | ||
+ | lda aaa+2 | ||
+ | adc bbb+2 | ||
+ | sta ccc+2 | ||
+ | </pre> | ||
+ | piszemy (zakładając, że ''aaa'', ''bbb'', ''ccc'' to zmienne w głównej pamięci): | ||
+ | <pre> | ||
+ | clc | ||
+ | ldx #$fd ;$fd = $00 - (liczba bajtów w jednej zmiennej) | ||
+ | add lda aaa-$fd,x | ||
+ | adc bbb-$fd,x | ||
+ | sta ccc-$fd,x | ||
+ | inx | ||
+ | bne add | ||
+ | </pre> | ||
+ | oszczędzając 13 bajtów pamięci. Gdy zmienne są na stronie zerowej, adresy należy zwiększyć: | ||
+ | <pre> | ||
+ | clc | ||
+ | ldx #$fd ;$fd = $00 - (liczba bajtów w jednej zmiennej) | ||
+ | add lda zaaa+3,x | ||
+ | adc zbbb+3,x | ||
+ | sta zccc+3,x | ||
+ | inx | ||
+ | bne add | ||
+ | </pre> | ||
+ | |||
+ | '''Ten ostatni przykład NIE będzie działał w trybie natywnym [[65C816]]''' (bo wygenerowany adres, zamiast "zawinąć" się przez koniec strony zerowej do jej początku, zyska wartość powyżej $00FF). | ||
[[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] |
Wersja z dnia 09:28, 11 kwi 2009
Ujemne indeksowanie używane przy wyszukiwaniu rosnącym, można zaoszczędzić w ten sposób porównanie w rejestrze indeksowym.
przykład: szukamy wartości A w łańcuchu TAB o długości L.
LDY #$ff-L _DO CMP TAB-($ff-L),Y BEQ _JEST INY BNE _DO
Operacje na wielu kolejnych bajtach, jak kopiowanie danych z miejsca na miejsce, dodawanie lub odejmowanie liczb wielobajtowych itd. dobrze jest w celu skrócenia programu zapętlić w podobny sposób.
Zwłaszcza arytmetyka jest często zapisywana w postaci "rozpętlonej", gdyż sterujący pętlą rozkaz CPX lub CPY zmienia znacznik C rejestru znaczników procesora kasując tym samym informację o przeniesieniu arytmetycznym. Łatwo się jednak tego problemu pozbyć. Zamiast:
clc lda aaa adc bbb sta ccc lda aaa+1 adc bbb+1 sta ccc+1 lda aaa+2 adc bbb+2 sta ccc+2
piszemy (zakładając, że aaa, bbb, ccc to zmienne w głównej pamięci):
clc ldx #$fd ;$fd = $00 - (liczba bajtów w jednej zmiennej) add lda aaa-$fd,x adc bbb-$fd,x sta ccc-$fd,x inx bne add
oszczędzając 13 bajtów pamięci. Gdy zmienne są na stronie zerowej, adresy należy zwiększyć:
clc ldx #$fd ;$fd = $00 - (liczba bajtów w jednej zmiennej) add lda zaaa+3,x adc zbbb+3,x sta zccc+3,x inx bne add
Ten ostatni przykład NIE będzie działał w trybie natywnym 65C816 (bo wygenerowany adres, zamiast "zawinąć" się przez koniec strony zerowej do jej początku, zyska wartość powyżej $00FF).