Converting numbers is very often used in assembler, because processors prefer calculating in binary, while people on a terminal prefer decimal numbers. If one has to communicate from within an assembler routine with one of the human species, number conversion is a must. This page provides some basic know how on number conversion. Learn a bit more in detail, how conversion between different number systems is done.

For those who prefer going directly to the source code, here is the link to the HTML version and the link to the asm version of the source code.

**Decimal**: Each byte represents a decimal digit, coded in ASCII. Decimal 49 or binary $30 represents the digit 0, decimal 49 the digit 1, and so on to 57, which represents a 9. Other numbers, from 0 to 47 and from 58 to 255, do not represent correct digits. (Why 0 is 48, and not 0, can only be understood historically, it reaches back to the times of US military teletype machines, but this is another long story).**BCD-numbers**: BCD means Binary Coded Decimal. It's like decimal ASCII, but the decimal digit zero here is indeed 0. BCDs reach from 0 to 9. Numbers greater than 9 (that is 10 to 255) are illegal and not BCD.**Binary numbers**: Here only the digits 0 and 1 are used. Read from the least significant bit, the value of the digits doubles, so the binary 1011 is equal 1*(2 ** 0) + 1*(2 ** 1) + 0*(2 ** 2) + 1*(2 ** 3). Just like decimal 1234 is equal to 4*(10 ** 0) + 3*(10 ** 1) + 2*(10 ** 2) + 1*(10 ** 3). (By the way: each number ** 0 is 1, except 0 ** 0, which is not known exactly). Binary numbers are handled in packages of 4 (called nibble), 8 (called Byte) or 16 (called word), because single bits are very small numbers and e.g. do not allow to buy five apples (needs a package of three bits).**Hex numbers**: Hex numbers are packages of four single bits. These four bits represent 16 different hex digits. The first ten are named like their decimal relatives, but the digits 10 to 15 are named A to F. As string of ASCII-coded hex digits this is rather unlucky, because the ASCII representation of the 9 is 57, of the A is 65. If you prefer using a..f for the additional six digits in hex, the ASCII representation is even 97. This is relevant for number conversions, because these hex digits are distributed over the ASCII character table, complicating conversion.

**Binary numbers:**All binaries are designed for 16 Bit, with values between 0 and 65,535. They are generally located in the register pair rBin1H (upper 8 bits, MSB) and rBin1L (lower 8 bits, LSB). This binary word is abbreviated as rBin1H:L. Preferred location for this word are the registers R2 and R1, but it doesn't really matter, where and in which order you place it. Some conversions require a second register pair, named rBin2H:L. You can place it in the registers R4 and R3. Generally the values in this register pair are restored after use, so you can use it for other purposes, too, without the risk of a conflict.**BCD- and ASCII-coded numbers:**These numbers are most often located somewhere in the SRAM space of the AVR, e.g. in a buffer of incoming characters from the SIO. So these numbers are generally handled with the pointer register Z (pointer register ZH:ZL or R31:R30). The numbers are assumed to be in the following order: The higher the value of the digit the lower the pointer adress. The number 12345 so would be located in SRAM like this: $0060: 1, $0061: 2, $0062: 3, and so on. You can also place the pointer Z to locations in the register space, e.g. to $0005. The 12345 would then be located like this: R5: 1, R6: 2, and so on. The conversion software so works as well in the register space, if you place the digits in that order to the registers. No need to write a special conversion routine for the register space. But beware of pointer bugs: the software overwrites registers without asking you. You can even overwrite the pointer registers ZH:ZL. What happens then is rather unknown. Thorough planning of the register space is a must, if you use that routines in register space.**Packaging:**Because not all conversion routines are necessary, I have packed the routines into four packages. The last two packages are only dedicated to hex conversions. The first package converts ASCII- and BCD-numbers to binaries, package II converts binaries to ASCII and BCD. Each package with the called subroutines in it runs separately. If you remove parts of the package content, be sure to keep the appropriated subroutines. The whole four packages compile to 217 words of program space.**Errors:**If a number conversion leads to an error, the T-flag is set to one. The T-flag can be used to react to an error, e.g. by using the branch instructions**BRTS**and**BRTC**. If you need the T-flag for other purposes, feel free to exchange the respective lines with the instructions**SET**,**CLT**,**BRTS**and**BRTC**to use a bit somewhere in a register. If an error is encountered the pointer Z points to the point of error. If the error is caused by an illegal character, it points to that character. If the error is an overflow error, the pointer points to the digit, where the error occurred.**Other rules:**Further details on the different routines are listed in the general part of the source code. There you'll find a overview on all rountines, showing all available functions, their calling conditions and their error cases.

If the length of the ASCII number is exactly five digits, you can use the routine Asc5ToBin2. Every illegal character causes an error, except leading blanks and zeros.

Conversion is done from the left to the right of the number. Each additional digit causes a multiplication of the result by 10, followed by adding the digit to the result. The routine is somewhat slow due to the multiplication by 10. There sure are quicker methods to do the conversion job. But this one is easy to understand.

If you use the routine Bin2ToAsc instead, the routine returns with the pointer Z on the first non-zero digit and the number of remaining digits in rBin2L. This is convenient if you have to send the result via SIO to the man behind the terminal without boring him with leading blanks.

The routine converts the hex digits A to F in capital letters. If you more like a to f, change the source code accordingly.

Zum Seitenanfang

©2002 by http://www.avr-asm-tutorial.net