Table of Contents
Application of DIV instruction in PIC microcontroller
Application of DIV instruction in PIC microcontroller. Why do we learn division in assembly? Assembler use division to convert decimal into binary, that’s why it is so important to learn. Other than this there are many benefits of division, it prints decimal of many bits and also used to check whether the given number is even or odd and many other division programs.
DIV/IDIV Instruction in microcontroller:
The division operation in assembly language generates two elements, a quotient and a remainder. Overflow does not occur in case of multiplication, because in that double-length registers are used to keep the product. But in the case of division there is a possibility of overflow. The DIV (divide) is used for unsigned data whereas IDIV (integer divide) is used for signed data. The format for the DIV/IDIV instruction −
DIV/IDIV divisor
In an accumulator is a dividend. Both of the division instructions can work with the 8-bit, 16-bit or 32-bit operands. All six status flags can be affected with operation. When the divisor is 1 byte 16-bit register is used in which quotient goes to AL register and remainder goes to AH register, when divisor is one word, 32-bit register is used in which quotient goes to AX register and remainder goes to HX register, and when divisor is doubleword, 64-bit register is used in which quotient goes to EAX register and remainder goes to EDX register.
Division of unsigned numbers:
In PIC18, there is not even a single instruction for division of byte/byte numbers. The program can be written only in this way that we perform division with repeated subtractions. By dividing a byte by a byte, nominator is placed in file reg whereas denominator is subtracted from it repeatedly. The remainder will be in filereg after completion while the quotient is number of times we subtracted. See the following example:
NUM EQU 0x19 ;set aside filereg
MYQ EQU 0x20
MYNMB EQU D‘95’
MYDEN EQU D’10’
CLRF MYQ ;Quotient = 0
MOVLW MYNMB ;WREG=95
MOVWF NUM ;Numerator is 95
MOVLW MYDEN ;WREG = denomerator = 10
B1 INCF MYQ, F ;increment quotient for every 10 subr
SUBWF NUM, F ;Subtract 10 (F = F – W)
BC B1 ;Keep doing it until c = 0
DECF MYQ, F ;once too many
ADDWF NUM, F ;add 10 back to get remaindar
Division for signed numbers:
Signed integers must be sign-extended before division takes place like fill high byte/word/doubleword with a copy of the low byte/word/doubleword’s sign bit. For example, the high byte contains a copy of the sign bit from the low byte. IDIV (signed divide) performs signed integer division it uses same operands as DIV.
Example: 8-bit division of –48 by 5
mov al,-48 cbw ;extend AL into AH
mov bl,5
idiv bl ; AL = -9, AH = -3
Flowchart of division:
An application for division:
Sometimes, an ADC (analog to digital converter) is connected to a port and the ADC represents some quantity like temperature or pressure. The data is provided by the ADC 8-bit in hex in the range of 00-FFH. This hex data is compulsory to be converted int decimal. 8086 has DIV instruction which is used to perform division. Take the 8-bit number into BL, and the 16-bit number into AX. Now divide AX by BL. The result will be stored at AX. The OF, SF, ZF, AR, PF and CF flags are undefined are undefined in performing division.
Divisor Operand Size | Dividend | Quotient | Remainder |
byte | AX | AL | AH |
word | DX:AX | AX | DX |
long | EDX:EAX | EAX | EDX |
If the resulting quotient is very large to fit in the destination, or if the divisor is 0, an Interrupt 0 is generated. Non-integral quotients will be truncated toward 0. The remainder will have the same sign as the dividend; the absolute value of the remainder is always less than the absolute value of the divisor.
Example:
Assume that file register location 0x15 has value FD (hex). write a program to convert it to decimal. save the digits in location 0x22, 0x23, and 0x24, where the least-significant digit is 0x22
Solution:
#include <P18F4550.INC>
;PIC assembly language program for division ( by repeated subtraction)
NUME EQU 0x15 ;RAM location for NUME
QU EQU 0x20 ‘RAM location for quotient
RMND_L EQU 0x22
RMND_M EQU 0x23
RMND_H EQU 0x24
MYNUM EQU 0xFD ;FDH = 253 in decimal
MYDEN EQU D’10’ ;253/10
ORG 0H ;starts at address 0
MOVLW MYNUM ;WREG = 253, the numerator
MOVWF NUME ;load numerator
MOVLW MY DEN ;WREG = 10, the denomerator
CLRF QU, F ;clear quotient
INCF QU, F ; increment quotient for every sub
SUBWF NUME ;sub WREG from NUME value
BC D_1 ;if positive go back
ADDWF NUME ;once too many, this is our first digit
DECF QU, F ;once too many for quotient
MOVFF NUME, RMND_L ;save the first digit
MOVFF QU, NUME ;repeat the process one more time
CLRF QU ;clear QU
D_2 INCF QU, F
SUBWF NUME ;SUB WREG from NUME value
BC D_2 ;(C = 1 for positive)
ADDWF NUME ;once too many
DECF QU, F
MOVFF NUME, RMND_M ;2nd digit
MOVFF QU, RMND_H ;3rd digit
HERE GOTO HERE ;stay here forever
END ; end of asm source file
Also read here for more