Programowanie: Mnożenie 16-bitowe z wynikiem 32-bitowym

From Atariki

(Różnice między wersjami)
Jump to: navigation, search
Wersja z dnia 06:52, 21 gru 2005
KMK (Dyskusja | wkład)

← Previous diff
Wersja z dnia 07:18, 21 gru 2005
KMK (Dyskusja | wkład)

Next diff →
Linia 53: Linia 53:
</pre> </pre>
-Procedura nie jest "optymalna", w szczególności można łatwo uniknąć kopiowania mnożnej do rejestru pomocniczego. Chodziło jednak o to, żeby procedura działała zgodnie z konwencją, jaką stosuje umieszczony w pamięci ROM komputera pakiet procedur zmiennoprzecinkowych - dla czterech działań arytmetycznych składniki są zawsze w FR0 i FR1, a wynik umieszczany jest w FR0. Przyjęcie takiej konwencji jest wygodne, gdy mamy w programie wykonać bardziej złożone obliczenie, zwłaszcza dłuższą serię mnożeń i dzieleń - wtedy wynik jednej procedury przechodzi w naturalny sposób jako składnik dalszych obliczeń do procedury następnej.+Procedura nie jest "optymalna", w szczególności można łatwo uniknąć kopiowania mnożnej do rejestru pomocniczego. Chodziło jednak o to, żeby procedura działała zgodnie z konwencją, jaką stosuje umieszczony w pamięci ROM komputera pakiet procedur zmiennoprzecinkowych - dla czterech działań arytmetycznych składniki są zawsze w FR0 i FR1, a wynik umieszczany jest w FR0. Przyjęcie takiej konwencji jest wygodne, gdy mamy w programie wykonać bardziej złożone obliczenie, zwłaszcza dłuższą serię mnożeń i [[Programowanie: Dzielenie 16-bitowe z wynikiem 32-bitowym|dzieleń]] - wtedy wynik jednej procedury przechodzi w naturalny sposób jako składnik dalszych obliczeń do procedury następnej.
Główna pętla zajmuje - w zależności od wartości mnożnika - od 612 do 944 cykli maszynowych. Główna pętla zajmuje - w zależności od wartości mnożnika - od 612 do 944 cykli maszynowych.
[[Kategoria:Niezbędnik kodera]] [[Kategoria:Niezbędnik kodera]]

Wersja z dnia 07:18, 21 gru 2005

Procedura mnoży dwie 16-bitowe liczby bez znaku umieszczone w rejestrach FR0 ($D4) i FR1 ($E0). 32-bitowy wynik umieszczany jest w FR0. Jeśli po zakończeniu procedury znacznik C jest ustawiony, oznacza to, że nastąpiło przepełnienie i wynik nie jest prawidłowy.

int16mul
?frf    =       fr1+2

        clc
        lda     fr0     ;gdy mnoznik albo mnozna jest zerem
        ora     fr0+1   ;to zerem jest rowniez wynik.
        beq     ?clr

        lda     fr1
        ora     fr1+1
        beq     ?clr

        ldx     #$01    ;kopiujemy mnozna do rejestru pomocniczego
?cp     lda     fr0,x
        sta     ?frf,x
        dex
        bpl     ?cp

        jsr     ?clr    ;zerujemy bajty wyniku

        ldx     #16
?mul    lsr     fr1+1   ;glowna petla
        ror     fr1
        bcc     ?noad

        clc
        lda     fr0+2
        adc     ?frf
        sta     fr0+2
        lda     fr0+3
        adc     ?frf+1
        sta     fr0+3
        bcs     ?exit

?noad   lsr     fr0+3
        ror     fr0+2
        ror     fr0+1
        ror     fr0
        dex
        bne     ?mul
        clc
?exit   rts

?clr    ldx #$03
        lda #$00
?cl     sta fr0,x
        dex
        bpl ?cl
        rts

Procedura nie jest "optymalna", w szczególności można łatwo uniknąć kopiowania mnożnej do rejestru pomocniczego. Chodziło jednak o to, żeby procedura działała zgodnie z konwencją, jaką stosuje umieszczony w pamięci ROM komputera pakiet procedur zmiennoprzecinkowych - dla czterech działań arytmetycznych składniki są zawsze w FR0 i FR1, a wynik umieszczany jest w FR0. Przyjęcie takiej konwencji jest wygodne, gdy mamy w programie wykonać bardziej złożone obliczenie, zwłaszcza dłuższą serię mnożeń i dzieleń - wtedy wynik jednej procedury przechodzi w naturalny sposób jako składnik dalszych obliczeń do procedury następnej.

Główna pętla zajmuje - w zależności od wartości mnożnika - od 612 do 944 cykli maszynowych.

Personal tools