Ujemne indeksowanie
From Atariki
| Wersja z dnia 14:47, 3 cze 2008 Xxl (Dyskusja | wkład) ← Previous diff |
Aktualna wersja KMK (Dyskusja | wkład) |
||
| Linia 1: | Linia 1: | ||
| - | Ujemne indeksowanie używane przy wyszukiwaniu rosnącym, można zaoszczędzić w ten sposób porównanie w rejestrze indeksowym. | + | Ujemne indeksowanie używane jest 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. | + | Przykład: w łańcuchu ''tab'' o długości ''n'' szukamy wartości przekazanej w akumulatorze: |
| <pre> | <pre> | ||
| - | LDY #$ff-L | + | LDY #-n |
| - | _DO CMP TAB-($ff-L),Y | + | _DO CMP tab-$0100+n,Y |
| - | BEQ _JEST | + | BEQ znaleziono |
| INY | INY | ||
| BNE _DO | BNE _DO | ||
| </pre> | </pre> | ||
| + | |||
| + | Operacje na wielu kolejnych bajtach, jak kopiowanie danych z miejsca na miejsce, dodawanie, odejmowanie lub porównywanie 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, a 'n' - rozmiar takowej w bajtach): | ||
| + | <pre> | ||
| + | clc | ||
| + | ldx #-n | ||
| + | add lda aaa-$0100+n,x | ||
| + | adc bbb-$0100+n,x | ||
| + | sta ccc-$0100+n,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 #-n | ||
| + | add lda zaaa+n,x | ||
| + | adc zbbb+n,x | ||
| + | sta zccc+n,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]] | ||
Aktualna wersja
Ujemne indeksowanie używane jest przy wyszukiwaniu rosnącym, można zaoszczędzić w ten sposób porównanie w rejestrze indeksowym.
Przykład: w łańcuchu tab o długości n szukamy wartości przekazanej w akumulatorze:
LDY #-n
_DO CMP tab-$0100+n,Y
BEQ znaleziono
INY
BNE _DO
Operacje na wielu kolejnych bajtach, jak kopiowanie danych z miejsca na miejsce, dodawanie, odejmowanie lub porównywanie 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, a 'n' - rozmiar takowej w bajtach):
clc
ldx #-n
add lda aaa-$0100+n,x
adc bbb-$0100+n,x
sta ccc-$0100+n,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 #-n
add lda zaaa+n,x
adc zbbb+n,x
sta zccc+n,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).
