Another way you can use those bits is BCD, Binary Coded Decimal. And it gives you no easy way to get the digits back out when you want to do anything with them.įootnote 1: Computers store everything in bits because they use binary logic, on or off, not 10 or 16 voltage levels. That won't work for numbers like 0xa5 since decimal only allows digits up to 9, and for smaller bases like 8 or 2 you can only store at most 1111111111 in a 32-bit integer, so that's only 10 bits. And it makes no sense, you have hex 0x50, not decimal 50.ĭon't do base-conversion by creating a binary integer whose decimal digits are the digits you want for some other base. You never want to have 0011 0010 (decimal 50) in a register in the first place: you could get that by multiplying 0b0101 by ten ( 0b1010), but the only way you could split it up again into 5 and 0 would be dividing by ten ( 0b1010), which is computationally much more difficult. (Thus we have to mask away the high 4 bits to emulate shifting them out.) AVR only has shifts by 1 bit at a time, except for swap which rotates by 4. So really it just took mov + swap + 2x andi instructions to isolate the two nibbles which we can then map to hex digits. That just made it possible to write a C function that produced both outputs so we could look at the compiler-generated asm. The storing is of course optional if you want to use the values right away, you don't need an array to store them in. (Godbolt) foo(unsigned char, unsigned char*):Īndi r25, 15 # emulate > 4 with SWAP + ANDI with 0xf Actually just 0.15 integers, not mapped to ASCII or 7-segment codes Out = in>4 // high hex digit is first in printing order In AVR assembly, you can isolate the two 4-bit halves of an 8-bit integer with and and swap instructions, like a compiler would make from this source void foo(unsigned char in, unsigned char *out) To get 7-segment-display codes, you might use a lookup table indexed by 4-bit integers. (Or to add an extra 7 ( 'A' - '0') for numbers above 10, so it's just an if, not if/else). To get ASCII codes, you could use a lookup table, or add '0' or 'A' depending on whether the nibble value is >= 10 or not. Note that the high 4 bits are 0101, binary for 5, and the low ( 0).īase 16 is a power of 2, so 4-bit groups of bits map to hex digits. In your case, 0b0101'0000 is decimal 80, hex 0x50 you could write the constant any of those 3 ways in C++ source code. A decimal or hex representation of that binary number is convenient for humans to look at, but that doesn't change what's actually in the register. The normal way 1 to have an integer in a register is pure binary, no decimal involved. Binary and decimal are two different number bases.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |