# How do I perform division of two numbers in PIC16F877A in assembly language?

I'm currently using MPLABX IDE to develop for a PIC16F877A microcontroller. I want to divide two numbers and find out the quotient (let the two numbers be 10 and 4) and store in a register.

I was thinking of a loop which increments the value of register by 1 every time 4 goes in 10 until it becomes zero or indivisible (as in integer).

I'm not able to figure out a way to make the controller recognize the end of division when either reminder is zero, negative or less than divisor.

I would appreciate any suggestions for accomplishing this using Assembly language.

• Welcome to EE.SE! This appears to be a homework question. As such, you need to show us your work so far, and explain which part of the question you're having trouble with. For future reference: Homework questions on EE.SE enjoy/suffer a special treatment. We don't provide complete answers, we only provide hints or Socratic questions, and only when you have demonstrated sufficient effort of your own. Otherwise, we would be doing you a disservice, and getting swamped by homework questions at the same time. See also here. Commented Oct 22, 2019 at 12:58
• Hint: Assuming the divisor is positive (and not zero), if the remainder is not less than the divisor, then you're not done yet. In other words, one test covers all three cases. Commented Oct 22, 2019 at 13:01
• For speed, look up not-restoring division algorithms. These can produce both quotient and remainder or just the quotient (rounded or truncated.) If speed isn't important, there are several options, all of them easy to look up. Also, PIC library code for their C compilers is free to look up and provides assembly code, as well. Lots of options.
– jonk
Commented Oct 22, 2019 at 13:24
• After each time you've subtracted 4 from 10 check the carry flag. If the carry flag is 0 then the numerator has gone negative at which point you would subtract 1 from the count value and add 4 back into the numerator to give the remainder.
– user173271
Commented Oct 22, 2019 at 13:31
• If not a homework question and speed (nor accuracy) is important, research which math libraries are available and the IEEE (vs. Microchip) floating-point format. It is possible to use floating-point math directly in PIC assembler. Commented Oct 22, 2019 at 14:05

This is another way:

;
; File: main.asm
; Target: PIC16F877A
; IDE: MPLABX v5.25
; Assembler: MPASM v5.84
;
; Description:
;
;   Show implementation and test of integer division.
;
;
; Notes:
;
;   Forum post: https://electronics.stackexchange.com/questions/463950/how-do-i-perform-division-of-two-numbers-in-pic16f877a-in-assembly-language
;
;
list    r=dec,n=0,c=132
errorlevel -302, -312
;
#include "p16F877A.inc"

__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF

#define FOSC (4000000)
#define FCYC (FOSC/4)
;
; Define macros to help
; with bank selection
;
#define BANK0  (h'000')
#define BANK1  (h'080')
#define BANK2  (h'100')
#define BANK3  (h'180')
;
;**********************************************************************
RESET_VECTOR code 0x000         ; processor reset vector
nop
goto    start               ; begin PIC initialization

;------------------------------------------------------------------------
start:
clrf    INTCON              ; Disable all interrupt sources
clrf    TMR0
banksel BANK1
clrf    PIE1
clrf    PIE2

movlw   b'11000000'         ; Pull-ups off, INT edge low to high, WDT prescale 1:1
movwf   OPTION_REG          ; TMR0 clock edge low to high, TMR0 clock = FCY, TMR0 prescale 1:2

movlw   b'11111111'         ;
movwf   TRISA

movlw   b'01111111'         ;
movwf   TRISB

movlw   b'11111111'         ;
movwf   TRISC

movlw   b'11111111'         ;
movwf   TRISD

; disable comparators
movlw   b'00000111'
movwf   CMCON

; Set all ADC inputs for digital I/O
movlw   b'00000110'

banksel BANK0
pagesel main
goto    main
;
; Interger 8x8 division with remainder
;
;   Quotient = Dividen / Divisor, with Remainder
;
; Input:    Dividen
;       Divisor
;
; Output:   Quotient in WREG
;       Remainder
;
Div8x8_DATA udata   0x20
Divisor     res     1
Dividen
Quotient    res     1
Remainder   res     1
BitCount    res     1

Div8x8_CODE code
Div8x8:
banksel BitCount
movlw   8
movwf   BitCount
clrf    Remainder
Div8x8Loop:
clrc
rlf     Dividen,F
rlf     Remainder,F
movf    Divisor,W
subwf   Remainder,W
skpnz
goto    BigEnough
skpc
goto    TooSmall
BigEnough:
movwf   Remainder
bsf     Dividen,0
TooSmall:
decfsz  BitCount,F
goto    Div8x8Loop
movf    Quotient,W
return
;
; Main application loop
;
MAIN_DATA   udata
Value1      res     1
Value2      res     1

MAIN_CODE code
main:
;
; Loop here forever testing Dividen and Divisors
;
ProcessLoop:
;
;
banksel Value1
clrf    Value1
decf    Value1,F

clrf    Value2
decf    Value2,F

TestLoop:
banksel Value1
movf    Value1,W
banksel Divisor
movwf   Divisor

banksel Value2
movf    Value2,W
banksel Dividen
movwf   Dividen

call    Div8x8

banksel Value1
decfsz  Value1,F
goto    TestLoop
decf    Value1,F

banksel Value2
decfsz  Value2,F
goto    TestLoop
decf    Value2,F

goto    ProcessLoop

end


If you are going to crib this for you homework at least you can add the comments.

@dan1138 was right this is the code for the pic18f45k22

Division_lOOP

movwf   NUMERATOR   ;numerator is set by working register before entering the loop
movlw   15
movwf   DENOMINATOR
movlw   8
movwf   BitCount
clrf    Remainder
Div8x8Loop:
bcf STATUS,C
RLCF    NUMERATOR,F     ;Rotates left if  carry
RLCF    Remainder,F     ;Rotates left if carry
movf    DENOMINATOR,W       ;moves lateral to working register
subwf   Remainder,W     ; Subtracts remainder from working register
BTFSC   STATUS,C        ;tests if carry has been set
goto    BigEnough
btfss   STATUS,C         ;tests if carry has not been set
goto    TooSmall
BigEnough:
movwf   Remainder       ;moves working register to remainder
bsf     NUMERATOR,0     ;sets Numbator bit

TooSmall:

decfsz  BitCount,F      ; decreases bit count
goto    Div8x8Loop
return


A very simple pseudo-code algorithm:
suppose you have to calculate X/Y = Q, to find Q :

q = 0
loop:
q++
x = q * Y
if x == X
Q = q
break
else if x > X                   goto loop
Q = q - 1
break
else
goto loop