Inkrementacja i dekrementacja liczb wielobajtowych: Różnice pomiędzy wersjami

Z Atariki
Przejdź do nawigacji Przejdź do wyszukiwania
Nie podano opisu zmian
 
0xF (dyskusja | edycje)
→Inkrementacja: szybszy kod
 
(Nie pokazano 4 wersji utworzonych przez 2 użytkowników)
Linia 1: Linia 1:
== Inkrementacja ==
== Inkrementacja ==


Sekwencja rozkazów zwiększająca wartość dwubajtowej liczby całkowitej jest powszechnie znana i często używana:
Sekwencja rozkazów zwiększająca wartość dwubajtowej liczby całkowitej o 1 jest powszechnie znana i często używana:


<pre>
<pre>
    inc zmienna
      inc zmienna
    bne omin
      bne koniec
    inc zmienna+1
      inc zmienna+1
omin
koniec
</pre>
</pre>


Linia 13: Linia 13:


<pre>
<pre>
    inc zmienna
      inc zmienna
    bne omin
      bne koniec
    inc zmienna+1
      inc zmienna+1
    bne omin
      bne koniec
    inc zmienna+2
      inc zmienna+2
omin
koniec
</pre>
</pre>


Niektóre asemblery (np. [[MADS]]) oferują tu ułatwiające życie pseudorozkazy, odpowiednio INW oraz INL.
Niektóre asemblery (np. [[MADS]]) oferują tu ułatwiające życie pseudorozkazy, odpowiednio INW oraz INL.


Technika ta przestaje się opłacać przy liczbach czterobajtowych; w takim przypadku lepiej jest użyć pętli oszczędzając w ten sposób 4 bajty:
W przypadku liczb trzy- i więcej-bajtowych krótszy kod można uzyskać stosując pętlę (n - wielkość ''zmiennej'' w bajtach):


<pre>
<pre>
    ldx #$fc
      ldx #-n
    sec
petla  inc zmienna-$0100+n,x
petla
      bne koniec
    lda zmienna-$fc,x
      inx
    adc #$00
      bne petla
    sta zmienna-$fc,x
koniec
    inx
</pre>
    bne petla
 
Jeśli zaś chodzi o przeniesienie inkrementowanej wartości do innej zmiennej, pętla może wyglądać tak:
 
<pre>
      ldx #-n
      sec
petla lda zmienna_a-$0100+n,x
      adc #$00
      sta zmienna_b-$0100+n,x
      inx
      bne petla
</pre>
</pre>


Wykorzystano tu fakt, że rozkaz ADC dodaje do akumulatora wartość podanego argumentu plus wartość znacznika C.
Wykorzystano tu fakt, że rozkaz ADC dodaje do akumulatora wartość podanego argumentu plus wartość znacznika C.
   
   
Taka pętla nie zadziała prawidłowo, jeśli "zmienna" znajduje się na stronie zerowej. Patrz [[Ujemne indeksowanie]].
Pętle nie zadziałają prawidłowo, jeśli ''zmienna'' znajduje się na stronie zerowej, do tego trzeba je odpowiednio zmodyfikować. Patrz [[Ujemne indeksowanie]].


== Dekrementacja ==
== Dekrementacja ==
Linia 45: Linia 55:


<pre>
<pre>
    lda zmienna
      lda zmienna
    bne d1
      bne d1
    dec zmienna+1
      dec zmienna+1
d1 dec zmienna
d1     dec zmienna
</pre>
</pre>


To z kolei przestaje się opłacać już przy liczbach trzybajtowych; lepiej jest wtedy użyć pętli podobnej do tej powyżej wykorzystując fakt, że działanie znacznika C dla rozkazu SBC jest odwrotne niż dla ADC (SBC odejmuje od akumulatora podaną wartość zwiększoną o odwrotność znacznika C):
Przy liczbach trzy- i więcej-bajtowych krótszy kod uzyskamy stosując pętlę podobną do tej powyżej, wykorzystując fakt, że działanie znacznika C dla rozkazu SBC jest odwrotne niż dla ADC (SBC odejmuje od akumulatora podaną wartość zwiększoną o odwrotność znacznika C):


<pre>
<pre>
    ldx #$fd
      ldx #-n
    clc
      clc
petla
petla lda zmienna-$0100+n,x
    lda zmienna-$fd,x
      sbc #$00
    sbc #$00
      sta zmienna-$0100+n,x
    sta zmienna-$fd,x
      inx
    inx
      bne petla
    bne petla
</pre>
</pre>


Dla liczby trzybajtowej (jakiej dotyczy przykład) zysk wynosi 5 bajtów, a dla czterobajtowej - aż 13. Jak powyżej, jeśli "zmienna" jest na stronie zerowej, pętlę trzeba odpowiednio zmodyfikować.
'n' to, jak powyżej, wielkość ''zmiennej'' w bajtach. Dla liczby trzybajtowej zysk wynosi 5 bajtów, a dla czterobajtowej - aż 13. Jak powyżej, jeśli ''zmienna'' jest na stronie zerowej, pętlę trzeba odpowiednio zmodyfikować.


[[Kategoria:Niezbędnik kodera]]
[[Kategoria:Niezbędnik kodera]]

Aktualna wersja z 5 wrz 2011, 12:20

Inkrementacja

Sekwencja rozkazów zwiększająca wartość dwubajtowej liczby całkowitej o 1 jest powszechnie znana i często używana:

       inc zmienna
       bne koniec
       inc zmienna+1
koniec

Sekwencja inkrementująca liczbę trzybajtową wygląda analogicznie:

       inc zmienna
       bne koniec
       inc zmienna+1
       bne koniec
       inc zmienna+2
koniec

Niektóre asemblery (np. MADS) oferują tu ułatwiające życie pseudorozkazy, odpowiednio INW oraz INL.

W przypadku liczb trzy- i więcej-bajtowych krótszy kod można uzyskać stosując pętlę (n - wielkość zmiennej w bajtach):

       ldx #-n
petla  inc zmienna-$0100+n,x
       bne koniec
       inx
       bne petla
koniec

Jeśli zaś chodzi o przeniesienie inkrementowanej wartości do innej zmiennej, pętla może wyglądać tak:

       ldx #-n
       sec
petla  lda zmienna_a-$0100+n,x
       adc #$00
       sta zmienna_b-$0100+n,x
       inx
       bne petla

Wykorzystano tu fakt, że rozkaz ADC dodaje do akumulatora wartość podanego argumentu plus wartość znacznika C.

Pętle nie zadziałają prawidłowo, jeśli zmienna znajduje się na stronie zerowej, do tego trzeba je odpowiednio zmodyfikować. Patrz Ujemne indeksowanie.

Dekrementacja

Dekrementacja dwubajtowej liczby całkowitej jest nieco bardziej kłopotliwa, niż inkrementacja takowej:

       lda zmienna
       bne d1
       dec zmienna+1
d1     dec zmienna

Przy liczbach trzy- i więcej-bajtowych krótszy kod uzyskamy stosując pętlę podobną do tej powyżej, wykorzystując fakt, że działanie znacznika C dla rozkazu SBC jest odwrotne niż dla ADC (SBC odejmuje od akumulatora podaną wartość zwiększoną o odwrotność znacznika C):

       ldx #-n
       clc
petla  lda zmienna-$0100+n,x
       sbc #$00
       sta zmienna-$0100+n,x
       inx
       bne petla

'n' to, jak powyżej, wielkość zmiennej w bajtach. Dla liczby trzybajtowej zysk wynosi 5 bajtów, a dla czterobajtowej - aż 13. Jak powyżej, jeśli zmienna jest na stronie zerowej, pętlę trzeba odpowiednio zmodyfikować.