divides one 16-bit value into another 16-bit value to compute a 16-bit result and remainder.
PBASIC allows you to divide any two variables--bits, bytes, words, or a mixture--to get a 16-bit result or remainder.
This routine duplicates that capability in assembly language. It uses a binary interpretation of the long-division method you were probably taught in school. It shifts the divisor left until there is a 1 in the msb. It then attempts to subtract this number from the dividend.
If the result of the subtraction is positive, the routine puts a 1 into the lsb of the quotient, shifts the quotient left, shifts the divisor right, and repeats the operation on what remains of the dividend. If the result of the subtraction is negative, the routine undoes the subtraction by adding the divisor and dividend back together, puts a 0 into the lsb of the quotient, shifts the quotient left, shifts the divisor right, and repeats the operation.
It may require a walk through the routine with paper and pencil (or the simulator) to grasp how this works. When the routine finishes, the 16-bit variable consisting of qH and qL holds the quotient or result of the division. The variable consisting of topH and topL holds the remainder.
Division by 0 is illegal, so the routine starts by checking for this. If division by 0 is attempted, the routine aborts and returns the error code 0FFh (255) in the w register. Otherwise, it returns with 0 in w. Your program should either prevent division by 0 or be prepared to act on the error code.
To see Divide in operation, either run the program with the PSIM simulator,
or connect the circuit below to an erasable PIC or PIC emulator, such as
the Parallax downloader. Assemble and run DIVIDE.SRC. When you apply power
to the PIC, the LEDs will light up in the binary pattern of the answer to
the math problem 330Ah/00A3h, which is 50h with a remainder of 1Ah. So the
quotient (50h) displays the following binary pattern on the LEDs:
0000 0000 0101 0000
Try dividing various values to see different results. Also, modify the program to display remainders (stored in the variables topH and topL) on the LEDs.
;
; ***************************************************************************
; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. ***
; *** http://www.bubblesoftonline.com email: sales@picnpoke.com ***
; ***************************************************************************
;
; DIVIDE
; Divide one 16-bit number into another, returning the 16-bit result and
; the remainder. Upon entry, the top of the division fraction (the dividend)
; must be in topH and topL, and the bottom (divisor) in btmH and btmL.
; If division by zero is attempted, the routine will return immediately with
; the error code of 0FFh in w. Otherwise, it will perform the division, leaving
; the remainder in topH and topL and the result (quotient) in qH and qL.
; Upon return from a successful division, w contains 0.
; Device data and reset vector
P = pic16c55
#include <16c55.inc> ; processor assembler definitions
_CONFIG _xt_osc & _wdt_off & _protect_off
reset start
org 8
topH Res d'1' ; MSB of top of fraction.
topL Res d'1' ; LSB of top of fraction.
btmH Res d'1' ; MSB of bottom of fraction.
btmL Res d'1' ; LSB of bottom of fraction.
qH Res d'1' ; MSB of quotient.
qL Res d'1' ; LSB of quotient.
count Res d'1' ; temporary counter
index Res d'1' ; temporary counter
org 0
start MOVLW d'0' ; Set to outputs to display
TRIS 6h
MOVLW d'0' ; results on LEDs.
TRIS 7h
MOVLW 0x33 ; Problem: divide
MOVWF topH
MOVLW 0x0A ; 330Ah by 00A3h.
MOVWF topL
MOVLW 0x00
MOVWF btmH
MOVLW 0x00A3
MOVWF btmL
CALL divide
MOVF qL,w ; Display quotient in binary
MOVWF 6h
MOVF qH,w ; on LEDs connected to rb and rc.
MOVWF 7h
GOTO $ ; Endless loop
Divide MOVF btmH,w ; Check for division by 0.
IORWF btmL,w
BTFSC status,z
RETLW d'255' ; Error code= 255: return.
MOVLW d'1' ; Otherwise, initialize variables
MOVWF count
CLRF index ; for the division.
CLRF qH
CLRF qL
Divide_sh_loop BTFSC btmH,d'7' ; Shift divisor left
GOTO Divide_d1
BCF status,c ; until msb is in
RLF btmL ; btmH.7.
RLF btmH ; count = no. of shifts+1.
INCF count
GOTO Divide_sh_loop
Divide_d1 BCF status,c
RLF qL ; Shift quotient left.
RLF qH
MOVF btmL,w ; top = top - btm.
SUBWF topL
BTFSC status,c ; If top - btm < 0 then
GOTO Divide_d2
MOVLW d'1' ; top = top + btm
SUBWF topH
BTFSC status,c ; The idea is to do the
GOTO Divide_d2
INCF topH ; the subtraction and comparison
MOVF btmL,w ; (top > btm?) in one step.
ADDWF topL
goto Divide_reentr ; Then, if btm > top, undo <Microchip instruction>
Divide_d2 MOVF btmH,w ; the subtraction by adding
SUBWF topH
BTFSS status,c ; top and btm back together
goto Divide_less ; <Microchip instruction>
BSF qL,d'0'
Divide_reentr
BCF status,c
RRF btmH
RRF btmL
DECFSZ count
GOTO Divide_d1
RETLW 0h ; Return w/ remainder in top
; and result in q.
Divide_less MOVF btmL,w ; btm > top, so
ADDWF topL
BTFSC status,c ; undo the subtraction by
INCF topH ; adding them back together.
MOVF btmH,w
ADDWF topH
goto Divide_reentr ; <Microchip instruction>
end
; DIVIDE ; Divide one 16-bit number into another, returning the 16-bit result and ; the remainder. Upon entry, the top of the division fraction (the dividend) ; must be in topH and topL, and the bottom (divisor) in btmH and btmL. ; If division by zero is attempted, the routine will return immediately with ; the error code of 0FFh in w. Otherwise, it will perform the division, leaving ; the remainder in topH and topL and the result (quotient) in qH and qL. ; Upon return from a successful division, w contains 0. org 8 topH ds 1 ; MSB of top of fraction. topL ds 1 ; LSB of top of fraction. btmH ds 1 ; MSB of bottom of fraction. btmL ds 1 ; LSB of bottom of fraction. qH ds 1 ; MSB of quotient. qL ds 1 ; LSB of quotient. count ds 1 ; temporary counter index ds 1 ; temporary counter ; Device data and reset vector device pic16c55,xt_osc,wdt_off,protect_off reset start org 0 start mov !rb,#0 ; Set to outputs to display mov !rc,#0 ; results on LEDs. mov topH,#33h ; Problem: divide mov topL,#0Ah ; 330Ah by 00A3h. mov btmH,#0h mov btmL,#0A3h call divide mov rb,qL ; Display quotient in binary mov rc,qH ; on LEDs connected to rb and rc. jmp $ ; Endless loop Divide mov w,btmH ; Check for division by 0. OR w,btmL snz retw 255 ; Error code= 255: return. mov count,#1 ; Otherwise, initialize variables clr index ; for the division. clr qH clr qL :sh_loop jb btmH.7,:d1 ; Shift divisor left clc ; until msb is in rl btmL ; btmH.7. rl btmH ; count = no. of shifts+1. inc count jmp :sh_loop :d1 clc rl qL ; Shift quotient left. rl qH sub topL,btmL ; top = top - btm. jc :d2 ; If top - btm < 0 then sub topH,#1 ; top = top + btm jc :d2 ; The idea is to do the inc topH ; the subtraction and comparison add topL,btmL ; (top > btm?) in one step. goto :reentr ; Then, if btm > top, undo :d2 sub topH,btmH ; the subtraction by adding sc ; top and btm back together goto :less setb qL.0 :reentr clc rr btmH rr btmL djnz count,:d1 ret ; Return w/ remainder in top ; and result in q. :less ADD topL,btmL ; btm > top, so snc ; undo the subtraction by inc topH ; adding them back together. ADD topH,btmH goto :reentr
See also:
| file: /Techref/microchip/seepicsrc/psbpix/division.htm, 14KB, , updated: 2001/5/25 14:48, local time: 2025/10/28 03:40,
216.73.216.22,10-3-83-201:LOG IN
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://www.piclist.com/Techref/microchip/seepicsrc/psbpix/division.htm"> microchip seepicsrc psbpix division</A> |
| Did you find what you needed? |
|
o List host: MIT, Site host massmind.org, Top posters @none found - Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr. |
|
The Backwoods Guide to Computer Lingo |
.