DIVISIONE
BINARIA A 8 BIT (intera senza segno) La divisione
consiste nel determinare quante volte un numero (il divisore)
e' contenuto in un altro (il dividendo), il risultato e' detto quoziente.
Un modo semplice per effettuare una divisione e' contare quante volte
si riesce a sottrarre il divisore dal dividendo senza ottenere un
valore negativo. Per esempio nella divisione 80/7 il 7 si riesce a
sottrarre per 11 volte, poi rimane un valore piu' piccolo di 7 detto resto
(nel nostro caso 3). Tuttavia se il dividendo e' un numero molto grande
e il divisore e' un numero molto piccolo (ad esempio 1), questa
procedura e' estremamente poco efficiente in quanto puo' richiedere un
numero elevatissimo di sottrazioni (infatti 255/1 richiederebbe ben 255
sottrazioni). Un algoritmo piu' efficiente e' invece quello di
riprodurre a livello binario lo stesso tipo di procedimento che si
mette in atto eseguendo una normale divisione decimale a mano su un
foglio di carta. Questo consiste nell'allineare le cifre del divisore a
sinistra sotto il dividendo, effettuare una sottrazione per vedere se
il divisore e' maggiore del dividendo, segnarsi uno 0 nel caso in cui
lo sia e un 1 nel caso in cui non lo sia, dopo di che shiftare il
divisore a destra di una posizione e ripetere l'operazione. Gli 0 e gli
1 che si ottengono come risultato della sottrazione si aggiungono mano
a mano sulla destra del quoziente facendolo scorrere verso sinistra.
Dopo n+1 cicli (dove n e' il numero di spostamenti effettuati
all'inizio per allineare il divisore a sinistra) nel quoziente si trova
il risultato della divisione, e nel dividendo risulta presente il resto
(0 se il divisore e' un sottomultiplo intero del dividendo). Con questo
procedimento verranno eseguite al massimo n+1 sottrazioni, cioe' 8 nel
caso peggiore. La subroutine seguente utilizza questo sistema, dapprima
vi e' un ciclo di allineamento a sinistra del divisore (evidenziato in
blu), seguito da quello delle n+1 sottrazioni. E' inutile ricordare che una divisione per
zero e' un' operazione impossibile e va assolutamente evitata. Nel
caso
di divisore=0 si rimane infatti bloccati all'infinito nel loop di
allineamento a sinistra in quanto il bit 7 di VL non diventara' mai 1.
;-----------------------------------------------------
; Divisione 8 bit intera senza segno
; Operazione: QL=DL/VL DL=resto
; IN: DL=dividendo VL=divisore
; OUT: QL=quoziente DL=resto
; CL = contatore di ciclo
;-----------------------------------------------------
DIV8
CLRF
QL ;Azzera
quoziente
CLRF
CL ;Azzera
contatore di ciclo
DIV8_2 INCF
CL,F ;CL=CL+1
BTFSC
VL,7 ;Se bit 7 di VL=0 skip
GOTO
DIV8_3 ;altrimenti vai a DIV8_3
BCF
STATUS,C ;Azzera carry
RLF
VL,F ;Ruota divisore a
sinistra
GOTO
DIV8_2 ;Vai a DIV8_2
DIV8_3
MOVF
VL,W ;W=divisore
SUBWF
DL,W ;W=dividendo-divisore
RLF
QL,F ;Ruota carry a destra
nel quoziente
BTFSC
QL,0 ;Se overflow skip
MOVWF
DL ;altrimenti
dividendo=W
BCF
STATUS,C ;Azzera carry
RRF
VL,F ;Ruota divisore a destra
DECFSZ
CL,F ;Decrementa
contat.ciclo, skip se 0
GOTO
DIV8_3 ;altrimenti vai a DIV8_3
RETURN
;Fine subroutine
;-----------------------------------------------------
DIVISIONE
BINARIA A 16 BIT (intera senza segno) La divisione a
16 bit sfrutta lo stesso identico principio di quella a 8 bit. La
difficolta' in piu' sta nel fatto che per ogni valore occorre usare una
coppia di registri da 8 bit anziche' uno solo. Queste coppie sono
chiamate QH:QL per il quoziente, VH:VL per il divisore ecc... L'unico
registro a 8 bit singolo che rimane e' il contatore di ciclo per le
sottrazioni, infatti al massimo verranno eseguite 16 sottrazioni. La
sottrazione a 16 bit (con regolazione corretta del flag C) e' stata
spostata in un'apposita subroutine perche' piuttosto complessa. Con
questo algoritmo la sottrazione tra dividendo e divisore altera il
valore del dividendo, per questo motivo, nel caso in cui si verifichi
un overflow (dividendo minore del divisore) e' successivamente
necessario ripristinare il valore del dividendo risommandolo con il
divisore, questa operazione e' detta restoring. Nella divisione
a 8 bit non si effettua nessun restoring in quanto il valore effettivo
del dividendo non viene alterato dalla sottrazione, e il nuovo
valore viene conservato in W e scritto nel dividendo solo in caso in
cui non vi sia overflow.
;-----------------------------------------------------
; Divisione 16 bit intera senza segno
; Operazione: QH:QL=DH:DL/VH:VL DH:DL=resto
; IN: DH:DL=dividendo VH:VL=divisore
; OUT: QH:QL=quoziente DH:DL=resto
; CL = contatore di ciclo FL = salvataggio flag
;-----------------------------------------------------
DIV16
CLRF QH
;Azzera quoziente
CLRF QL
CLRF
CL ;Azzera
contatore di ciclo
DIV16_2 INCF
CL,F ;CL=CL+1
BTFSC
VH,7 ;Se bit 7 di VH=0 skip
GOTO DIV16_3
;altrimenti vai a DIV16_3
BCF
STATUS,C ;Azzera carry
RLF
VL,F ;Ruota divisore a
sinistra
RLF VH,F
GOTO
DIV16_2 ;Vai a DIV16_2
DIV16_3
CALL
SUB16 ;Chiama sottraz. DH:DL-VH:VL
RLF
QL,F ;Ruota carry a destra
nel quoziente
RLF QH,F
BTFSS
QL,0 ;Se non overflow skip
CALL RESTORING
;altrimenti chiama somma DH:DL+VH:VL
BCF
STATUS,C ;Azzera carry
RRF
VH,F ;Ruota divisore a destra
RRF VL,F
DECFSZ
CL,F ;Decrementa
contat.ciclo, skip se 0
GOTO
DIV16_3 ;altrimenti vai a DIV16_3
RETURN
;Fine subroutine
;-----------------------------------------------------
; DH:DL = DH:DL -
VH:VL (con regolazione corretta flag C)
; FL = salvataggio intermedio flag C
;-----------------------------------------------------
SUB16
BSF
FL,4 ;Imposta a 1 il bit 4 di
FL
MOVF
VL,W ;W=parte bassa divisore
SUBWF
DL,F ;ao sottrae a parte
bassa dividendo
BTFSC STATUS,C
;Se overflow skip
GOTO
SUB16_2 ;altrimenti vai a SUB16_2
MOVLW 1
SUBWF
DH,F ;Sottrae 1 a parte alta
dividendo
SWAPF STATUS,W
;Salva i flag in FL
MOVWF FL
SUB16_2
MOVF
VH,W ;W=parte alta divisore
SUBWF
DH,F ;la sottrae a parte alta
dividendo
BTFSS
FL,4 ;Controlla bit 4 di FL,
se 1 skip
BCF
STATUS,C ;altrimenti resetta carry
RETURN
;-----------------------------------------------------
; DH:DL = DH:DL +
VH:VL (senza regolazione flag C)
;-----------------------------------------------------
RESTORING
MOVF
VL,W ;W=parte bassa divisore
ADDWF
DL,F ;la somma a parte bassa
dividendo
BTFSC STATUS,C
;Se non overflow skip
INCF
DH,F ;altrimenti incrementa
parte alta dividendo
MOVF
VH,W ;W=parte alta divisore
ADDWF
DH,F ;la somma a parte alta
dividendo
RETURN
;-----------------------------------------------------
By
Claudio Fin - Pagina creata nel febbraio 2004 - Ultimo
aggiornamento 27-3-2004