Before we can discuss memory, we must first learn hexadecimal counting.
We count with ten different digits, and a number represents coefficients multiplied by different powers of 10. For example, $543$ is equal to $5$ hundreds ($= 10^2$) plus $4$ tens ($= 10^1$) plus $3$ ones ($= 10^0$).
When counting, once we reach 9, we carry a 1 and add that to the coefficient of the next higher power of ten.Nothing requires us to have 10 digits, and its almost the worst possible base other than perhaps base $7$, $11$ or $19$. One base that is more convenient for computers is base 16, so we now have sixteen different digits:
0 1 2 3 4 5 6 7 8 9 a b c d e f
Now, you could set up addition and multiplication tables in base 16, so $9 + 3 = c$, $f + 1 = 10$, $ff + 1 = 100$, $9 \cdot 4 = 1c$, and $d^2 = a9$, but this isn't necessary here.
Instead, all you need to do is understand how to count in hexadecimal.
First, we will represent hexadecimal numbers by prefixing them by 0x, so 0x32 is a hexadecimal number and not thirty-two. Instead, 0x32 means $3 \times 16 + 2 = 50$.
Next, the number that comes before 0x32 is 0x31 ($= 49$), and the number that comes after is 0x33 ($= 51$).
Similarly, the number that comes after 0x3d49 is 0x3d4a, and the number after that is 0x3d4b.
The number after 0x3d4f is 0x3d50, the number after 0x3d9f is 0x3da0, and the number after 0x32adfff is 0x32ae000.
Addresses tend to be stored in multiples of 2, 4 or 8, so starting at 0xff8a3d0 and counting by twos:
0xff8a3d0 0xff8a3d2 0xff8a3d4 0xff8a3d6 0xff8a3d8 0xff8a3da 0xff8a3dc 0xff8a3de 0xff8a3e0 0xff8a3e2 0xff8a3e4
Starting at the same number but counting by four:
0xff8a3d0 0xff8a3d4 0xff8a3d8 0xff8a3dc 0xff8a3e0 0xff8a3e4 0xff8a3e8 0xff8a3ec 0xff8a3f0
Starting at the same number but counting by eight:
0xff8a3d0 0xff8a3d8 0xff8a3e0 0xff8a3e8 0xff8a3f0 0xff8a3f8 0xff8a400 0xff8a408 0xff8a410
For humor, however, here are the words to a song written by Paul McCarthy rewritten for hexadecimal:
Two and two are four Four and four are eight Eight and eight are ten (0x10) Ten and ten are twenty (0x20) Hex worm, hex worm Measuring the memory You and your arithmetic You'll probably go far Twenty and twenty are forty Forty and forty are eighty Eighty and eighty are one hundred (0x100) One hundred and a hundred are two hundred (0x20) Hex worm, hex worm Measuring the memory Seems to me you'd stop and see How binary they are
A 32-bit computer has $2^{32} = 2^{4 \times 8} = (2^4)^8 = 16^8$ possible different addresses. Each byte has a different address, and thus the maximum number of bytes that can have different addresses are $2^{32}$ or approximately four billion (hence four gigabytes). Thus, any address of a 32-bit computer can be written with exactly eight hexadecimal numbers.
0x00000000 First byte in memory 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009 0x0000000a 0x0000000b 0x0000000c 0x0000000d 0x0000000e 0x0000000f 0x00000010 . . . . 0xffffffef 0xfffffff0 0xfffffff1 0xfffffff2 0xfffffff3 0xfffffff4 0xfffffff5 0xfffffff6 0xfffffff7 0xfffffff8 0xfffffff9 0xfffffffa 0xfffffffb 0xfffffffc 0xfffffffd 0xfffffffe 0xffffffff Last byte in memory
On a 64-bit system, addresses can be up to 64 bits long, or 16 hexadecimal characters; however, currently no one on the planet has sufficient memory to allow each address to be used—this would 18 quintillion bytes, or almost 17 million terabytes of memory.
At the other end, microcontrollers may have address buses as small as 16 bits; such microcontrollers can only access 64 kilobytes of memory. One long-running microprocessor that used only 16 bit addresses is the Motorola 6800. First introduced in 1974, it was last produced in 2006.
We will be referring to memory locations in future lessons, but for the most part, everything discussed here should be sufficient.
As you are likely aware, memory is divided into bytes, and each byte has its own address. Each byte is 8 bits, and thus, there are $2^8$ different values a byte can store. Note that $2^8 = 2^{4 \times 2} = (2^4)^2 = 16^2$, so to represent all possible values of a byte, you need only two hexadecimal characters:
Binary Hex Decimal 00000000 0x00 0 00000001 0x01 1 00000010 0x02 2 00000011 0x03 3 00000100 0x04 4 00000101 0x05 5 00000110 0x06 6 00000111 0x07 7 00001000 0x08 8 00001001 0x09 9 00001010 0x0a 10 00001011 0x0b 11 00001100 0x0c 12 00001101 0x0d 13 00001110 0x0e 14 00001111 0x0f 15 00010000 0x10 16 00010001 0x11 17 00010010 0x12 18 00010011 0x13 19 00010100 0x14 20 00010101 0x15 21 . . . . . . . . . 01111001 0x79 121 01111010 0x7a 122 01111011 0x7b 123 01111100 0x7c 124 01111101 0x7d 125 01111110 0x7e 126 01111111 0x7f 127 10000000 0x80 128 10000001 0x81 129 10000010 0x82 130 10000011 0x83 131 10000100 0x84 132 10000101 0x85 133 10000110 0x86 134 . . . . . . . . . 11101001 0xe9 233 11101010 0xea 234 11101011 0xeb 235 11101100 0xec 236 11101101 0xed 237 11101110 0xee 238 11100111 0xef 239 11110000 0xf0 240 11110001 0xf1 241 11110010 0xf2 242 11110011 0xf3 243 11110100 0xf4 244 11110101 0xf5 245 11110110 0xf6 246 11110111 0xf7 247 11111000 0xf8 248 11111001 0xf9 249 11111010 0xfa 250 11111011 0xfb 251 11111100 0xfc 252 11111101 0xfd 253 11111110 0xfe 254 11111111 0xff 255