Converting 8bit BIN to BCD equivalent [ASM]

Posted on 2006-04-09
Last Modified: 2009-07-29
i need to convert 8bit BIN to BCD.
I need a small and fast way of convertioning in ASM.

I am stuck!, please help ASAP.
I need to finish a project by wednesday

Carlos P
Question by:carlospzx
    LVL 1

    Expert Comment

    You didn't specify what flavor of assembler. Here's a version using C syntax with very simple operations. You should be able to convert pretty readily to any particular assembly language.

    This version assumes a 32 bit number. If you need fewer bits, you can reduce the maximum digit supported.

    Because you want fast, the easiest thing is to unroll all the digit processing. This removes any need for an integer divide, the slowest assembly instruction.

    I used a set_digit() macro from C to simplify understanding. Every assembler I've ever programmed has had a macro language more powerful than the C preprocessor, so this shouldn't present much of a challenge.

    If you don't know how to do a 'while' statement in assembly, it usually looks like this:

    #  while (test) { stuff }
    # jumpto TEST
    # LOOP:
    # stuff
    # TEST:
    # test the condition
    # branch-if-true, LOOP

    There are two flavors of BCD in common use. The most basic BCD encoding simply takes the value (0-9) of two decimal digits and puts them into the high- and low- nibbles of a byte, respectively:

    19 -> 1,9 -> byte[1 9] -> byte[0001 1001]

    That's "1 << 4" in C, and uses what are called "bit shifting" operators. For your processor it may be called "left shift" or "shift left".

    To join the two nibbles, high and low, you treat them as bytes with 4 interesting bits set. To start with:
    0000HHHH - high nibble value (0000 0001  = 0x01)
    0000LLLL - low nibble value (0000 1001 = 0x09)

    Then you move (shift left) the high nibble to the left:

    1 << 4
    HHHH0000 = 0001 0000 = 0x10

    Then you "bitwise or" or "logical or" the two values together

    0x10 | 0x09

    HHHHLLLL -> 0x19

    That is the simple BCD form. Various processors, including the 8080, 6502, and 68000 families, had special purpose instructions for dealing with data in this form, so if you intend to do complex math with the data this is where you need to be.

    But transferring BCD in this form is a chore, because the byte values frequently include 0x00 and sending 0x00 across the internet (or just to a C language routine) is dangerous.

    So rather than expand the BCD out to ascii bytes (simple, but wasteful of space) there is an "advanced form" of BCD that avoids nul bytes and low-order ascii characters (but does require 8-bit safe transmission). That form takes the BCD and does a binary NOT operation (most CPUs have this as a single opcode).

    The encoded digit values 9 and 0 are the extreme cases for BCD. Look at their representation:

    99 = 1001 1001
    90 = 1001 0000
    09 = 0000 1001
    00 = 0000 0000

    The problems here are with 00, which is a NUL when expressed as ASCII, and 09 (TAB).

    By inverting the bits, we get:

    99 = 0110 0110
    90 = 0110 0000
    09 = 1111 0110
    00 = 1111 1111

    The lowest possible ASCII byte is 0110 0000 = 0x60, the back-tick (`). This avoids the NULs and other control-sequence bytes, but does require that transmission support high-bit (aka 8-bit) characters. I

    If you want just simple encoding, return at the end of the simple encoding section. If you also want the advanced encoding, continue through to the end.

    long accum;
    char buffer[10];

    buf_x = 0;

    #define set_digit(DIGIT) \
          while (accum >= DIGIT) \
                ++buffer[buf_x]; \


          set_digit( 1000000000 );
          set_digit(  100000000 );
          set_digit(   10000000 );
          set_digit(    1000000 );
          set_digit(     100000 );
          set_digit(      10000 );
          set_digit(       1000 );
          set_digit(        100 );
          set_digit(         10 );
          buffer[buf_x] = accum; // 1s digit

          char digits[6];
          int digit_x;
          /* This approach does not use digits[6], but see below. */
          buf_x = 0;
          for (digit_x = 0; digit_x < 5; ++digit_x) {
                digits[digit_x] = (buffer[buf_x] << 4) | buffer[buf_x + 1];
                buf_x += 2;

          for (digit_x = 0; digit_x < 5; ++digit_x)
                digits[digit_x] = ~digits[digit_x];
          digits[5] = 0;

    Author Comment


    I am programming in MPLAB for the Microchip's 16f877a. I am kind of limited in the set of intruction.
    Please help me out

    LVL 1

    Expert Comment


    I've never even heard of the 16f877a until today. Do you have access to a C compiler? (Many C compilers will generate assembly language programs if you ask.)


    Author Comment


    Sorry, i've probably missed guide you. I am programing on a electronic microproccesor from microchip.
    LVL 14

    Accepted Solution

    Here's an algorithm that jumped to my mind: :-)
    (we will use the binary value 237 as an example)

    1. Assume that we have the binary value stored in variable x (x can take values from 0 to 255)
    2. Let y=(x/10)*10
        Since x=237, therefore y=230
    3. Let n=x-y
        Now n=7
    4. Let y=(x/100)*10
        Since x=237, therefore y=20
    5. Let o=(x/10)-y
        Now o=23-20=3
        Shift o 4 bits to the left, and add the result to n. Now n=37 (in hexadecimal representation)
    6. Let m=x/100
        Since x=237, therefore m=2
    7. Now m contains 02, and n contains 37 (hex.), which is the BCD representation of 237

    The above algorithm uses the following instructions: DIV (division), MUL (multiplication), SUB (subtraction), ADD (addition), and SHL (shift left).
    Note that DIV and MUL instructions can be implemented using loops (if not supported).


      Nayer Naguib

    Featured Post

    Threat Intelligence Starter Resources

    Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

    Join & Write a Comment

    I know it’s not a new topic to discuss and it has lots of online contents already available over the net. But Then I thought it would be useful to this site’s visitors and can have online repository on vim most commonly used commands. This post h…
    Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
    Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
    In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

    728 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now