Question:
Please explain how do do this BCD stuff (binary coded decimal) :S?
mike
2009-12-07 02:37:25 UTC
I have some questions phrased as the following...(where ive put * there's a number but i want to understand the method, not just get an answer :) )
What is the code for the number * using **** binary coded decimal (BCD)?
thanks
Four answers:
Alan Y
2009-12-07 07:18:41 UTC
Most of the time you would only translate a binary number into a binary coded decimal number for outputting the text version of that number. Unlike the old world 6502 microprocessor there is no binary coded decimal switch in the flags register of the PC and the floating point maths co-processor which is now built into the PC processor uses IEEE format and is still binary. Making it impossible to do actual binary coded decimal mathematics using the PC. The translation of binary to binary coded decimal and then to ASCII text is done for you when using high level languages such as C or C++, BASIC and so on. You would only need to do this if you were programming the computer in Assembler (machine code), in which case you divide the binary number by 1010 binary (HA0 hexidecimal, 10 decimal) and store the remainder in to memory, this would have to be done several times to translate the whole of the binary number in to binary coded decimal. Before doing so and assuming the binary number is an integer (a positive/negative number) the binary number would have to be made positive first.



In 8086 assembler lanuage it would be written something like this:



Put a space character in to the first byte of the variable called textnumber, the space is ASCII character 32



move AL,32

mov [textnumber],AL



Move into the AX register the binary number



mov AX, Binary_number



Check for negative number, if the value of the 16 bit number is 32768 or greater then the most signicant bit is high which means the number is negative



cmp AX,32768



jl means jump if less meaning the value in the AX register is lest than (in this case) 32768.



jl number_is_positive



Negate the number, a negative number becomes positive, neg is the same as multipling a number by -1



neg AX



Push the AX register onto the stack and load the AL register with the minus sign and store the AL into the first byte if the textnumber variable.



push AX

mov AL,'-

mov [textnumber],AL



Retrive the binary number from the stack

pop AX



Here the translation is done, the maximum numer of decimal digits that a 16 bit number is translated into is 5, -32768 to 32767 for integer numbers and 0 to 65535 for positive only numbers

:number_is_positive



Move into the SI register the number 5



mov SI,5



Move into the BX register the value of 10 decimal



mov BX,10



:loophere

Divide the AX register by the value in the BX register (10 decimal)



div BX



The modulas or remainder is stored in the DX register, we are only interested in the lower byte of the DX register (DL), the remainder of a divide by 10 can only be a value from 0 to 9.



You don't have to do this, but to print the answer to the screen you will need to translate the value in the DL register to ASCII text, the ASCII code for the numbers 0 to 9 is H30 to H39. The lower nybble is 0 to 9 and the upper nybble is 3 in hexdecimal or 48 decimal. Thus OR in the hexdecimal number H30 to the value in the DL register.



or DL,H30



Store the result into the variable textnumber with increment form start of textnumber memory location



mov [textnumber+SI],DL



'Decement the SI register by 1 and jump not equal to zero back to the label loophere



dec SI

jne loophere



Return from subroutine



ret



Alocated 6 bytes of memory to store, the first byte will have a space or minus sign stored in it, the rest will have ASCII text for the decimal number.



textnumber db 0,0,0,0,0,0





You may want or need to write a subroutine to get rid or the leading zeros. If you don't want to translate into ASCII text then do not OR the hex value 30 into the DL register and write a subroutine to compact the answer so 2 decimal digits are store in one byte.



In short, translating binary in to binary coded decimal you divide the number by decimal 10 and store the remainder in a right to left fashion. Not unlike converting a decimal number in to binary where you would divide the decimal number by 2 until there is no number left to divide and write the remainders down in a right to left fashion IE 25 in binary is



25/2 = 12 remainder 1

12/2 = 6 remainder 0

6/2 = 3 remainder 0

3/2 = 1 remainder 1

1/2 = 0 remainder 1



25 decimal = 11001 binary.



Just in case you don't know this.



AX register is the 16 bit Accumulator Register.

AL register is the lower byte of the AX register.

DX register is the 16 bit Data Register.

DL register is the lower byte of the DX register.

BX register is the Base register.

SI register is the Source Index register.
Mary
2016-05-27 07:08:16 UTC
BCD is simply binary where the bits are split into blocks of 4. For each block the valid values are between 0 and 9, anything over 9 is invalid. e.g. 25 = 0010 0101 in BCD Binary values of 1010 or higher are invalid BCD makes for easy conversion to and from decimal so it has uses in simple input and output situations but it's very wasteful in terms of hardware (only 10 of the 16 possible values are used for each block) and it's overly complex to build things that work internally in BCD unless you have a very good reason to do so. Hex is base 16. Decimal is base 10 and has 10 valid values (0 to 9), the next digit to the left is then multiplied by 10 e.g. 25 = 2 * 10 + 5 Hex is exactly the same but with 16 possible values (0 to 9 and then A to F). (A = 10, B = 11 etc...) e.g. 25 (in hex) = 2*16 + 5 = 37 (in decimal) 19 (in hex) = 1*16 + 9 = 25 (in decimal) 1A (in hex) = 1*16 + 10 = 26 (in decimal) Hex is used in computing because 4 bits of binary gives 16 possible values making conversion from hex to binary and back very easy with a little practice. Computers work in binary but humans don't, it's all too easy to make a mistake or miscount when you have a string of 32 0's or 1's. Hex is used as a compromise, it's a lot easier for humans to use than binary but almost as easy for the computer to cope with. It also makes it far clearer how much difference there is in binary between 2 numbers. e.g. in decimal 64 and 96 don't seem to have much in common but in hex they are 40 and 60, making it far clearer that in binary they are very similar. The normal convention is for hex numbers to be written starting with 0x to make it clear it's in hex e.g. binary, hex, BCD, decimal 0000 = 0x0 = 0000 = 0 0001 = 0x1 = 0001 = 1 ... 1000 = 0x8 = 1000 = 8 1001 = 0x9 = 1001 = 9 1010 = 0xa = 0001 0000 = 10 1011 = 0xb = 0001 0001 = 11 1100 = 0xc = 0001 0010 = 12 1101 = 0xd = 0001 0011 = 13 1110 = 0xe = 0001 0100 = 14 1111 = 0xf = 0001 0101 = 15 Octal is much the same as hex only base 8 rather than 16. Each octal digit maps to 3 binary bits rather than 4. This has the plus that you only need to use normal numbers rather than resorting to letters, for some reason using letters confuses some people. Why do this? In the real world I've never used octal. I've only used BCD once or twice, I've used base 36 more. Binary and hex on the other hand I use all the time. Computers work on bytes, blocks of 8 bits. In decimal that gives a range of 0 to 255, in octal it's 0 to 377 and in hex it's 0 to FF. If I see a number like 175426 I have no idea how many bits or bytes that will take. If I see the same number in octal (526502) I still have no idea off hand how many bytes that is since 1 bytes takes 2 and 2/3's digits. I also couldn't easily tell you what the second byte of the binary representation was without decoding most of the digits. But in hex it's 2AF42, it'll take 3 bytes to store (0000 0010, 1010 1111, 0100 0010). More importantly with a bit of practice I can convert that hex number into binary in my head faster than I could get my calculator to do the same task and just as easily convert just part of it if I only need a subsection.
Swtf
2009-12-07 02:49:46 UTC
try wikipedia.org



0111 = 7 (0001b = 1d, 0010b = 2d, 0100b = 4d)

from the right, each digit you move to the left is double the last digit.

if digit is on (1) it is added.



8 4 2 1 (implied)

0 1 1 1 = 0 + 4 + 2 + 1 = 7



maybe some1 else can explain better
2009-12-07 02:43:40 UTC
http://en.wikipedia.org/wiki/Binary-coded_decimal


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...