Section 2.7 Memory
We now have the language necessary to begin discussing the major components of a computer. We start with the memory.
There are two general kinds of memory used for storing program instructions and data in a computer.
- Random Access Memory (RAM)
-
Once a bit (switch) is set to either zero or one, it stays in that state until the control unit actively changes it or the power is turned off. The control unit can both read the state of each bit and change it.
The terminology used here is inconsistent. “Random access” means that it takes the same amount of time to access any byte in the memory, not that randomness is involved. This is in contrast to memory that is sequentially accessible, e.g., tape, where the length of time it takes to access a byte depends upon the physical location of the byte with respect to the current position of the tape.
- Read Only Memory (ROM)
The bits are permanently set. The control unit can read the state of each bit but cannot change it. Some types of ROM can be reprogrammed with specialized hardware, but the bits remain in the new state when the power is turned off.
You can think of memory as a (very long) array of bytes. Each byte has a particular location (or address) within this array. That is, you could think of
memory[123] |
as specifying the \(124^{th}\) byte in memory. (Don't forget that array indexing starts with 0 in most programming languages.) Each byte in memory is numbered. We generally do not use array notation and simply use the index number, calling it the address or location of the byte.
The address of a particular byte never changes. That is, the \(957^{th}\) byte from the beginning of memory will always remain the \(957^{th}\) byte. However, the state of each of the bits—either \(\binary{0}\) or \(\binary{1}\)—in any given byte can be changed.
Computer scientists typically express the address of each byte in memory in hexadecimal. So we would say that the \(957^{th}\) byte is at address \(\hex{3bc}\text{.}\)
From the discussion of hexadecimal in Section 2.1 we can see that the first sixteen bytes in memory have the addresses \(\hex{0}\text{,}\) \(\hex{1}\text{,}\) \(\hex{2}\text{,}\) \(\hex{3}\text{,}\) \(\hex{4}\text{,}\) \(\hex{5}\text{,}\) \(\hex{6}\text{,}\) \(\hex{7}\text{,}\) \(\hex{8}\text{,}\) \(\hex{9}\text{,}\) \(\hex{a}\text{,}\) \(\hex{b}\text{,}\) \(\hex{c}\text{,}\) \(\hex{d}\text{,}\) \(\hex{e}\text{,}\) and \(\hex{f}\text{.}\) Using the notation
address: | contents (bit pattern at the address) |
we could show the (possible) contents (the state of the bits) of each of the first sixteen bytes of memory as in Table 2.7.1. Pay particular attention to the fact that two hexadecimal characters exactly specify the state of each of the eight bits in a byte.
\(\hex{00000000}\text{:}\) | \(\hex{6a}\) | \(\hex{00000008}\text{:}\) | \(\hex{f0}\) | |
\(\hex{00000001}\text{:}\) | \(\hex{f0}\) | \(\hex{00000009}\text{:}\) | \(\hex{02}\) | |
\(\hex{00000002}\text{:}\) | \(\hex{5e}\) | \(\hex{0000000a}\text{:}\) | \(\hex{33}\) | |
\(\hex{00000003}\text{:}\) | \(\hex{00}\) | \(\hex{0000000b}\text{:}\) | \(\hex{3c}\) | |
\(\hex{00000004}\text{:}\) | \(\hex{ff}\) | \(\hex{0000000c}\text{:}\) | \(\hex{c3}\) | |
\(\hex{00000005}\text{:}\) | \(\hex{51}\) | \(\hex{0000000d}\text{:}\) | \(\hex{3c}\) | |
\(\hex{00000006}\text{:}\) | \(\hex{cf}\) | \(\hex{0000000e}\text{:}\) | \(\hex{55}\) | |
\(\hex{00000007}\text{:}\) | \(\hex{18}\) | \(\hex{0000000f}\text{:}\) | \(\hex{aa}\) |
A bit can be used to store data. For example, we could use a single bit to indicate whether a student passes a course or not. We might use \(\binary{0}\) for “not passed” and \(\binary{1}\) for “passed.” A single bit allows only two possible values of a data item. We cannot for example, use a single bit to store a course letter grade—A, B, C, D, or F.
How many bits would we need to store a letter grade? Consider all possible combinations of two bits:
\(\binary{00}\) |
\(\binary{01}\) |
\(\binary{10}\) |
\(\binary{11}\) |
Since there are only four possible bit combinations, we cannot represent all five letter grades with only two bits.
Let us add another bit and look at all possible bit combinations:
\(\binary{000}\) |
\(\binary{001}\) |
\(\binary{010}\) |
\(\binary{011}\) |
\(\binary{100}\) |
\(\binary{101}\) |
\(\binary{110}\) |
\(\binary{111}\) |
With eight possible bit combinations, we have more than enough bits to store any of the letter grades. For example, we could use the code:
Letter Grade | Bit Pattern |
A | \(\hex{000}\) |
B | \(\hex{001}\) |
C | \(\hex{010}\) |
D | \(\hex{011}\) |
F | \(\hex{100}\) |
This example illustrates two issues that a programmer must consider when storing data in memory in addition to its location(s):
How many bits are required to store the data? In order to answer this we need to know how many different values are allowed for the particular data item. Study the two examples above—two bits and three bits—and you can see that adding a bit doubles the number of possible values. Also, notice that we might not use all the possible bit patterns within an allocated space.
What is the code for storing the data? Most of the data we deal with in everyday life is not expressed in terms of zeros and ones. In order to store it in computer memory, the programmer must decide upon a code of zeros and ones to use. In the above (three bit) example we used \(\hex{000}\) to represent a letter grade of ‘A’, \(\hex{001}\) to represent ‘B’, etc.
For example, in our course grade example, a programmer may choose to store the letter grade at byte number \(\hex{befff64a}\) in memory. If the grade is ‘A’, the programmer would set the bit pattern at location \(\hex{befff64a}\) to \(\hex{00}\text{,}\) if the grade is ‘C’, the programmer would set the bit pattern to \(\hex{02}\text{,}\) etc. In this example, one of the jobs of an assembly language programmer would be to determine how to set the bit pattern at byte number \(\hex{befff64a}\) to the appropriate value.
High-level languages use data types to specify the number of bits and the storage code. For example, in C you may choose to store the letter grades in the above example in a char
variable and use the characters ‘A’, ‘B’,…,‘F’ to indicate the grade. In Section 2.13 you will learn that the compiler would use the following storage formats:
Letter Grade | Bit Pattern |
A | \(\hex{41}\) |
B | \(\hex{42}\) |
C | \(\hex{43}\) |
D | \(\hex{44}\) |
F | \(\hex{46}\) |
And programming languages, even assembly language, allow programmers to create symbolic names for memory addresses. The compiler (or assembler) determines the correspondence between the programmer's symbolic name and the numerical address. The programmer can refer to the address by simply using the symbolic name.