Programowanie: Mnożenie 16-bitowe z wynikiem 32-bitowym
From Atariki
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.
6502
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
Główna pętla zajmuje - w zależności od wartości mnożnika - od 612 do 944 cykli maszynowych.
65C816
int16mul ?frf = fr1+2 .aw .ib rep #$21 ;CPU musi byc w trybie natywnym sep #$10 lda fr0 ;gdy mnoznik albo mnozna jest zerem beq ?clr ;to zerem jest rowniez wynik. lda fr1 beq ?clr lda fr0 ;kopiujemy mnozna do rejestru pomocniczego sta ?frf jsr ?clr ;zerujemy bajty wyniku ldx #16 ?mul lsr fr1 ;glowna petla bcc ?noad clc lda fr0+2 adc ?frf sta fr0+2 bcs ?exit ?noad lsr fr0+2 ror fr0 dex bne ?mul clc ?exit rts ?clr stz fr0 stz fr0+2 rts
Główna pętla zajmuje max. 656 cykli maszynowych.
Uwagi
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.