Programowanie: Dzielenie 16-bitowe z wynikiem 32-bitowym
From Atariki
(Różnice między wersjami)
| Wersja z dnia 07:14, 21 gru 2005 KMK (Dyskusja | wkład) ← Previous diff |
Aktualna wersja KMK (Dyskusja | wkład) (w sumie po co dwa razy odejmowanie ...) |
||
| Linia 1: | Linia 1: | ||
| Procedura dzieli 16-bitową liczbę bez znaku umieszczoną we FR0 ($D4) przez takąż liczbę umieszczoną w FR1 ($E0). 16-bitowy wynik całkowity umieszczany jest w FR0, a 16-bitowa reszta z dzielenia w FR0+2. Opuszczenie procedury z ustawionym znacznikiem C sygnalizuje przepełnienie. | Procedura dzieli 16-bitową liczbę bez znaku umieszczoną we FR0 ($D4) przez takąż liczbę umieszczoną w FR1 ($E0). 16-bitowy wynik całkowity umieszczany jest w FR0, a 16-bitowa reszta z dzielenia w FR0+2. Opuszczenie procedury z ustawionym znacznikiem C sygnalizuje przepełnienie. | ||
| + | |||
| + | == 6502 == | ||
| <pre> | <pre> | ||
| int16div | int16div | ||
| - | lda fr1 ;dzielnik musi byc wiekszy od zera | + | lda fr1 ;dzielnik musi byc wiekszy od zera |
| - | ora fr1+1 | + | ora fr1+1 |
| - | beq ?e | + | beq ?e |
| - | lda fr0 ;dzielnik wiekszy od dzielnej | + | ; <-- czesc pomijalna |
| - | cmp fr1 ;daje w wyniku zero, a dzielna | + | lda fr0 ;dzielnik wiekszy od dzielnej |
| - | lda fr0+1 ;stanowi reszte | + | cmp fr1 ;daje w wyniku zero, a dzielna |
| - | sbc fr1+1 | + | lda fr0+1 ;stanowi reszte |
| - | bcs ?div | + | sbc fr1+1 |
| + | bcs ?div | ||
| - | ldx #$01 | + | lda fr0 |
| - | ?d lda fr0,x | + | sta fr0+2 |
| - | sta fr0+2,x | + | lda fr0+1 |
| - | dex | + | sta fr0+3 |
| - | bpl ?d | + | lda #$00 |
| - | lda #$00 | + | sta fr0 |
| - | sta fr0 | + | sta fr0+1 |
| - | sta fr0+1 | + | |
| rts | rts | ||
| + | ; --> | ||
| - | ?div lda #$00 ;kasujemy reszte | + | ?div lda #$00 ;kasujemy reszte |
| - | sta fr0+2 | + | sta fr0+2 |
| - | sta fr0+3 | + | sta fr0+3 |
| - | ldx #16 | + | ldx #16 |
| - | ?l asl fr0 | + | ?l asl fr0 |
| - | rol fr0+1 | + | rol fr0+1 |
| - | rol fr0+2 | + | rol fr0+2 |
| - | rol fr0+3 | + | rol fr0+3 |
| - | lda fr0+2 | + | sec |
| - | cmp fr1 | + | lda fr0+2 |
| - | lda fr0+3 | + | sbc fr1 |
| - | sbc fr1+1 | + | tay |
| - | bcc ?s | + | lda fr0+3 |
| + | sbc fr1+1 | ||
| + | bcc ?s | ||
| - | lda fr0+2 | + | sty fr0+2 |
| - | sbc fr1 | + | sta fr0+3 |
| - | sta fr0+2 | + | |
| - | lda fr0+3 | + | |
| - | sbc fr1+1 | + | |
| - | sta fr0+3 | + | |
| - | inc fr0 | + | inc fr0 |
| - | bne ?s | + | bne ?s |
| - | inc fr0+1 | + | inc fr0+1 |
| - | bne ?s | + | bne ?s |
| ?e sec | ?e sec | ||
| Linia 56: | Linia 57: | ||
| ?s dex | ?s dex | ||
| - | bne ?l | + | bne ?l |
| clc | clc | ||
| Linia 62: | Linia 63: | ||
| </pre> | </pre> | ||
| - | Procedura jest "kompatybilna" z procedurą [[Programowanie: Mnożenie 16-bitowe z wynikiem 32-bitowym|mnożenia]] (quod vide). | + | Główna pętla zajmuje - w zależności od składników - od 624 do 1152 cykli maszynowych. |
| - | Główna pętla zajmuje - w zależności od składników - od 832 do 1456 cykli maszynowych. | + | == 65C816 == |
| + | |||
| + | <pre> | ||
| + | int16div | ||
| + | .aw | ||
| + | .ib | ||
| + | rep #$20 ;CPU musi byc w trybie natywnym | ||
| + | sep #$10 | ||
| + | |||
| + | lda fr1 ;dzielnik musi byc wiekszy od zera | ||
| + | beq ?e | ||
| + | |||
| + | ; <-- czesc pomijalna | ||
| + | lda fr0 ;dzielnik wiekszy od dzielnej | ||
| + | cmp fr1 ;daje w wyniku zero, a dzielna | ||
| + | bcs ?div ;stanowi reszte | ||
| + | |||
| + | lda fr0 | ||
| + | sta fr0+2 | ||
| + | stz fr0 | ||
| + | rts | ||
| + | ; --> | ||
| + | |||
| + | ?div stz fr0+2 ;kasujemy reszte | ||
| + | |||
| + | ldx #16 | ||
| + | |||
| + | ?l asl fr0 | ||
| + | rol fr0+2 | ||
| + | |||
| + | sec | ||
| + | lda fr0+2 | ||
| + | sbc fr1 | ||
| + | bcc ?s | ||
| + | |||
| + | sta fr0+2 | ||
| + | |||
| + | inc fr0 | ||
| + | bne ?s | ||
| + | |||
| + | ?e sec | ||
| + | rts | ||
| + | |||
| + | ?s dex | ||
| + | bne ?l | ||
| + | |||
| + | clc | ||
| + | rts | ||
| + | </pre> | ||
| + | |||
| + | Elegancka procedura biblioteczna powinna jeszcze przechowywać na stosie i przed powrotem do miejsca wywołania przywracać rozmiar rejestrów. W powyższym przykładzie pominięto to, żeby nie zaciemniać zagadnienia. | ||
| + | |||
| + | == Uwagi == | ||
| + | |||
| + | Procedura jest "kompatybilna" z procedurą [[Programowanie: Mnożenie 16-bitowe z wynikiem 32-bitowym|mnożenia]] (quod vide). | ||
| [[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] | ||
Aktualna wersja
Procedura dzieli 16-bitową liczbę bez znaku umieszczoną we FR0 ($D4) przez takąż liczbę umieszczoną w FR1 ($E0). 16-bitowy wynik całkowity umieszczany jest w FR0, a 16-bitowa reszta z dzielenia w FR0+2. Opuszczenie procedury z ustawionym znacznikiem C sygnalizuje przepełnienie.
[Edytuj]
6502
int16div
lda fr1 ;dzielnik musi byc wiekszy od zera
ora fr1+1
beq ?e
; <-- czesc pomijalna
lda fr0 ;dzielnik wiekszy od dzielnej
cmp fr1 ;daje w wyniku zero, a dzielna
lda fr0+1 ;stanowi reszte
sbc fr1+1
bcs ?div
lda fr0
sta fr0+2
lda fr0+1
sta fr0+3
lda #$00
sta fr0
sta fr0+1
rts
; -->
?div lda #$00 ;kasujemy reszte
sta fr0+2
sta fr0+3
ldx #16
?l asl fr0
rol fr0+1
rol fr0+2
rol fr0+3
sec
lda fr0+2
sbc fr1
tay
lda fr0+3
sbc fr1+1
bcc ?s
sty fr0+2
sta fr0+3
inc fr0
bne ?s
inc fr0+1
bne ?s
?e sec
rts
?s dex
bne ?l
clc
rts
Główna pętla zajmuje - w zależności od składników - od 624 do 1152 cykli maszynowych.
[Edytuj]
65C816
int16div
.aw
.ib
rep #$20 ;CPU musi byc w trybie natywnym
sep #$10
lda fr1 ;dzielnik musi byc wiekszy od zera
beq ?e
; <-- czesc pomijalna
lda fr0 ;dzielnik wiekszy od dzielnej
cmp fr1 ;daje w wyniku zero, a dzielna
bcs ?div ;stanowi reszte
lda fr0
sta fr0+2
stz fr0
rts
; -->
?div stz fr0+2 ;kasujemy reszte
ldx #16
?l asl fr0
rol fr0+2
sec
lda fr0+2
sbc fr1
bcc ?s
sta fr0+2
inc fr0
bne ?s
?e sec
rts
?s dex
bne ?l
clc
rts
Elegancka procedura biblioteczna powinna jeszcze przechowywać na stosie i przed powrotem do miejsca wywołania przywracać rozmiar rejestrów. W powyższym przykładzie pominięto to, żeby nie zaciemniać zagadnienia.
[Edytuj]
Uwagi
Procedura jest "kompatybilna" z procedurą mnożenia (quod vide).
