Skoki do adresów w tablicy: Różnice pomiędzy wersjami
przeniesienie |
inny sposob |
||
| (Nie pokazano 2 wersji utworzonych przez 2 użytkowników) | |||
| Linia 1: | Linia 1: | ||
Są sytuacje, gdzie chcemy skoczyć pod różny adres w zależności np od wartości rejestru Y. | Są sytuacje, gdzie chcemy skoczyć pod różny adres w zależności np od wartości rejestru Y. | ||
Przykładowym rozwiązaniem jest trzymanie tablicy adresów, podzielonych na lo/hi adres | Przykładowym rozwiązaniem jest trzymanie tablicy adresów, podzielonych na lo/hi adres i użycie automodyfikacji kodu (ten sam kod dla JSR i JMP): | ||
<pre> | <pre> | ||
lda skoki_lo,y ; 4 cykle | lda skoki_lo,y ; 4 cykle | ||
| Linia 51: | Linia 50: | ||
</pre> | </pre> | ||
Oszczędzamy 6 cykli, bo usuwamy lda/sta (-8 cykli), ale zwiększamy koszt JMP z 3 do 5 (+2). | Oszczędzamy 6 cykli, bo usuwamy lda/sta (-8 cykli), ale zwiększamy koszt JMP z 3 do 5 (+2). | ||
Można także użyć rozkazu BNE | |||
<pre> | |||
lda mul3,y ; 4 cykle | |||
sta _skok+1 ; 4 | |||
_skok bne $FF ; 3 | |||
jmp skok0 ; 3 cykle | |||
jmp skok1 | |||
... | |||
jmp skokN ; max N to 42 | |||
</pre> | |||
[[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] | ||
Aktualna wersja z 17 cze 2011, 13:00
Są sytuacje, gdzie chcemy skoczyć pod różny adres w zależności np od wartości rejestru Y. Przykładowym rozwiązaniem jest trzymanie tablicy adresów, podzielonych na lo/hi adres i użycie automodyfikacji kodu (ten sam kod dla JSR i JMP):
lda skoki_lo,y ; 4 cykle sta _skok+1 ; 4 lda skoki_hi,y ; 4 sta _skok+2 ; 4 _skok jsr adres ; 6, lub JMP, 3 cykle
Innym sposobem na wykonanie skoku jest wykorzystanie właściwości rozkazu RTS. Nadal potrzebujemy tablic adresów, podzielonych na lo/hi adres-1 (koniecznie adres pomniejszony o 1). Takie rozwiązanie użyteczne jest w przypadku programów na karcie gdzie nie mamy możliwości automodyfikacji kodu.
lda skoki_hi,y ; 4 cykle pha ; 3 lda skoki_lo,y ; 4 pha ; 3 rts ; 6 = 20 cykli
Dla JSR, w sytuacji, gdy liczba skoków jest ograniczona do 86, możemy stworzyć specjalną dodatkową tablicę, zawierającą nie adresy skoków, ale rozkazy JMP, tzn:
skoki jmp skok1 ; 3 cykle jmp skok2 ... jmp skokN ; max N to 86
Jeśli ten kod umieścimy tak, że skoki rozpoczynają się na początku strony, możemy użyć następującej konstrukcji:
lda mul3,y ; 4 cykle sta _skok+1 ; 4 _skok jsr skoki ; 6
W ten sposób zaoszczędzamy 5 cykli, bo unikamy lda/sta (-8 cykli) ale dodajemy pośredni jmp (+3), kosztem dodatkowej pamięci.
Dla JMP, możemy to zrobić jeszcze inaczej, używając rozkazu JMP (adres). Nasza tablica skoki powinna zawierać po kolei adresy docelowe, czyli:
skoki dta a(skok1) dta a(skok2) ... dta a(skokN) ; max N to 128
I teraz nasz kod zamieniamy na
tya ; 2 cykle asl @ ; 2, mnożymy przez 2 sta _skok+1 ; 4 _skok jmp (skoki) ; 5
Oszczędzamy 6 cykli, bo usuwamy lda/sta (-8 cykli), ale zwiększamy koszt JMP z 3 do 5 (+2).
Można także użyć rozkazu BNE
lda mul3,y ; 4 cykle sta _skok+1 ; 4 _skok bne $FF ; 3 jmp skok0 ; 3 cykle jmp skok1 ... jmp skokN ; max N to 42