An Introduction to Binary and Hexadecimal
Becoming familiar with basic binary and hexadecimal (hex) math will make your career
in embedded systems far more enjoyable. Shifting individual bits around is great when
you need to modify only one or two places. But if you need to modify the whole variable,
hex comes in handy because each digit in hex corresponds to a nibble (four bits) in
binary. (Yes, of course a nibble is half of a byte. Embedded folks like their puns.)
Binary |
Hex |
Decimal |
Remember this number |
0000 |
0 |
0 |
This one is easy. |
0001 |
1 |
1 |
This is (1 << 0). |
0010 |
2 |
2 |
This is (1<< 1). Shifting is the same as multiplying by 2^{shiftValue}. |
0011 |
3 |
3 |
3 Notice how in binary this is just the sum of one and two. |
0100 |
4 |
4 |
(1 << 2). |
0101 |
5 |
5 |
This is an interesting number because every other bit is set. |
0110 |
6 |
6 |
6 See how this looks like you could shift the three over to the left by one? This could be put together as ((1<<2)|(1<<1)), or ((1<<2) + (1<<1)), or (3 << 1)). |
0111 |
7 |
7 |
7 Look at the pattern of binary bits. They are very repetitive. Learn the pattern, and you’ll be able to generate this table if you need to. |
1000 |
8 |
8 |
(1 << 3). See how the shift and the number of zeros are related? If not, look at the binary representation of 2 and 4. |
1001 |
9 |
9 |
We are about to go beyond the normal decimal numbers. Because there are more digits in hexadecimal, we’ll borrow some from the alphabet. In the meantime, 9 is just 8 + 1. |
1010 |
A |
10 |
This is another special number with every other bit set. |
1011 |
B |
11 |
See how the last bit goes back and forth from 0 to 1? It signifies even and odd. |
1100 |
C |
12 |
Note how C is just 8 and 4 combined in binary? So of course it equals 12. |
1101 |
D |
13 |
The second bit from the right goes back and forth from 0 to 1 at half the speed of the first bit: 0, then 0, then 1, then 1, then repeat. |
1110 |
E |
14 |
The third bit also goes back and forth, but at half the rate of the second bit. |
1111 |
F |
15 |
All of the bits are set. This is an important one to remember. |
Note that with four bits (one hex digit) you can represent 16 numbers, but you can’t
represent the number 16. Many things in embedded systems are zero-based, including
addresses, so they map well to binary or hexadecimal numbers.
A byte is two nibbles, the left one being shifted up four spaces from the other. So 0x80
is (0x8 << 4). A 16-bit word is made up of two bytes, so 0x1234 is (0x12 << 8) + (0x34).
A 32-bit word is 8 characters long in hex but 10 characters long in decimal.
Since memory is generally viewed in hex, some values are used to identify anomalies
in memory. In particular, expect to see (and use) 0xDEADBEEF or 0xDEADC0DE as
an indicator (they are a lot easier to remember in hex than in decimal). Two other
important bytes are 0xAA and 0x55. Because the bits in these numbers alternate, they
are easy to see on an oscilloscope and good for testing when you want to see a lot of
change in your values.
This was taken from a sidebar in my book Making Embedded Systems.