0

Converting between binary and decimal in assembly

Posted by Keith on Oct 22, 2009 in Uncategorized

One of the interesting challenges in working in assembly, versus C, is converting between BCD and binary. We all know that processors work in binary and users work in C, right? The problem is, even thought some processors include BCD math capabilities, things like multiplication, division, and all the system timers, work in binary.

So, one of the long standing problems, is how do we efficiently convert between base 2 and base 10. Well, a couple of years ago, I was faced with this problem, and I came up with a fairly efficient conversion algorithm that works well in both directions.

The routines are based on the same basic principal as a multiply routine. For example, let’s convert an 8-bit binary number to BCD.

8-bit binary value 10110101

First, we build up a constant table for each bit location;

0 0 1

0 0 2

0 0 4

0 0 8

0 1 6

0 3 2

0 6 4

1 2 8

Then we create a set of BCD output variables and clear them

BCD100 BCD10 BCD1

Next, we shift through the binary value, and for every 1, we add the corresponding value from the table, using BCD addition;

8-bit binary value 10110101

0 0 1

0 0 4

0 1 6

0 3 2

+ 1 2 8

—————————————

1 8 1

To go in the other direction, we just use a binary array of constants, and add using binary addition

BCD value 181

Binary constants

00000001 1

00000010 2

00000100 4

00001000 8

00001010 10

00010100 20

00101000 40

01010000 80

01100100 100

11001000 200

And the conversion looks like this;

BCD value 181

01100100 100

01010000 80

+ 00000001 1

———————————-

10110101

Of course, this technique can be expanded to any number of bits; all you need to do is expand the constant table to include all the bit values. Attached to the end of this blog are listings for both binary to decimal and decimal to binary for the PIC16FXXX family of parts;

;************************************************************************

; Converts a 5 digit BCD to 16-bit number in H_byte:L_byte

; Limitation: 5-digit bcd must be less than 2^17 (= 65536) in order

; to fit into the 16-bit result. Else result is remainder.

;

; R2H R2L R1H R1L R0H R0L

; - dig5 dig4 dig3 dig2 dig1

BCD5BIN16:

clrf H_byte

movf R2, W

andlw 0×0F

movwf L_byte

call mpy10a ; result = 10a+b

swapf R1, W

call mpy10b ; result = 10[10a+b]

movf R1, W

call mpy10b ; result = 10[10[10a+b]+c]

swapf R0, W

call mpy10b ; result = 10[10[10[10a+b]+c]+d]

movf R0, W

andlw 0×0F

addwf L_byte, F

btfsc STATUS, C

incf H_byte, F ; result = 10[10[10[10a+b]+c]+d]+e

return ; BCD to binary conversion done

mpy10b:

andlw 0×0F

addwf L_byte, F

btfsc STATUS, C

incf H_byte, F

mpy10a:

bcf STATUS, C ; multiply by 2

rlf L_byte, W

movwf L_temp

rlf H_byte, W ; (H_temp,L_H_temp) = 2*N

movwf H_temp

bcf STATUS, C ; multiply by 2

rlf L_byte, F

rlf H_byte, F

bcf STATUS, C ; multiply by 2

rlf L_byte, F

rlf H_byte, F

bcf STATUS, C ; multiply by 2

rlf L_byte, F

rlf H_byte, F ; (H_byte,L_byte) = 8*N

movf L_temp, W

addwf L_byte, F

btfsc STATUS, C

incf H_byte, F

movf H_temp, W

addwf H_byte, F

return ; (H_byte,L_byte) = 10*N

;*********************************************************************

;———————————————————————

; Bin16BCD

; Converts 16-bit binary number (H_byte:L_byte) into a 5 digit

; BCD number in 5 nibbles of registers R2, R1, R0 as shown.

;

; R2H R2L R1H R1L R0H R0L

; - dig5 dig4 dig3 dig2 dig1

;———————————————————————

Bin16BCD:

bcf STATUS,C ; clear the carry bit in STATUS

movlw .16

movwf temp+1

clrf R0

clrf R1

clrf R2

b16b_loop16:

rlf L_byte, F

rlf H_byte, F

rlf R0, F

rlf R1, F

rlf R2, F

decfsz temp+1, F

goto adjDEC

return

adjDEC:

movlw R0

movwf FSR

call adjBCD

movlw R1

movwf FSR

call adjBCD

movlw R2

movwf FSR

call adjBCD

goto b16b_loop16

adjBCD:

movlw 0×03

addwf INDF,W

movwf temp

btfsc temp,3 ; test if result > 7

movwf INDF

movlw 0×30

addwf INDF,W

movwf temp

btfsc temp,7 ; test if result > 7

movwf INDF ; save as MSD

return

Tags: ,

Copyright © 2013 Notes from the Lab All rights reserved. Theme by Laptop Geek.