INTRODUCTION TO ADDRESSING TECHNIQUES
To begin our discussion of addressing techniques, let's first define the term. As used throughout this book, the term addressing refers to the way we tell the 6502 what memory location we wish to operate on. For example, BASIC has two addressing modes. The first is a direct mode in which the memory location (address) in question is specified directly, for example:
20 POKE 752,1
25 V = PEEK(764)
25 V = PEEK(764)
Line 20 tells the computer to put the value 1 into memory location 752. Line 25 tells the computer to look directly into memory location 764, get the value stored there, and then store this value into a variable called V This direct accessing of one particular memory location is called direct addressing.
The second system used in BASIC is more subtle, and is also implied by line 25 above. When we tell the computer to take the value from memory location 764 and store it into a place called V, we, as programmers, don't care where V actually is. It's enough that the computer knows where V is stored, and that it knows how to retrieve the correct value when we refer to V from this point on. We'll call this form indirect addressing.
Both of these BASIC modes have counterparts in assembly language, and we'll discuss them later in this chapter. Many other addressing modes are also available from assembly language: let's first use a nonprogramming example to see why it is advantageous to be able to use more than one or two addressing modes.
Imagine a very large apartment building with thousands of apartments, so large that it dwarfs anything else in the world. It has 256 floors, making it the world's tallest building by far, and each floor has 256 apartments. In fact, this building is so large that it has its own postal system. Now let's think for a moment about how we tell the poor letter carrier how and where to deliver internal mail to the residents of this huge building. By the way, this building is named the 6502 Building, since it reminded the architects of a computer based on the 6502 chip, with 256 pages of memory each containing 256 memory locations.
We can, of course, give the letter carrier a specific letter with instructions to deliver it to apartment 5-004. The carrier would then take the elevator to the fifth floor and slide the letter into the slot in the door marked 004. Since we gave an absolute address, which didn't vary, or depend on any other information, we could refer to this as absolute addressing.
The ground floor of our building is occupied by many of the offices which are required to keep a building of this size running, and of course they'll need to receive mail also. If the address we specify on the letter is 0-032, we have a special case of the absolute address. The letter carrier doesn't need to use the elevator to reach a ground-floor address, so this letter can be delivered much more quickly. In fact, it has even become standard for residents to omit the first zero if the mail is destined for the ground floor, floor 0, and simply put 032 on the envelope. Our letter carrier knows this is a quick delivery and runs it right over. Letters to these offices are very important and must be delivered immediately. Since this is a special case of the absolute address, in which we don't even specify the floor, we'll call it zero floor addressing.
These two addressing systems both specify the exact absolute address on the envelope. Now suppose that we want to send a bulk mailing to everyone on floor 123. We could, of course, address each of the 256 letters individually, but this would take a long time. Instead, we might simply hand the letter carrier 256 letters and a note with instructions to deliver one of the enclosed letters to each apartment on floor 123. The carrier would then take the elevator to the 123d floor, and then walk along the halls, dropping letters in the slots on the doors and counting 1, 2, 3.... With any luck at all, the carrier would get to apartment 123-256 with one letter left, and deliver it. This type of address requires a count offset from the floor address, in order to get the apartment number. For instance, the 12th letter must go to apartment 123 plus 12, or number 123012. Our count is an index that tells us which apartment on this floor we have reached; we'll refer to this type of addressing as indexed addressing. We shall see that several different indexed addressing modes are used in the 6502 building.
If we lived in apartment 230-042, we could stop the letter carrier who delivered our mail, and request that a letter be delivered to an apartment five doors down from us. In this case, we don't have to mention the apartment number; the letter carrier can figure it out. The apartment to which this letter is delivered depends on the apartment from which it was sent. In our example, the letter ends up in apartment 230-047, but if the same message were given to the letter carrier by the owner of apartment 024-128, then the letter would be delivered to apartment 024-133. Therefore, this addressing system is relative to the address of the originating apartment; we'll call this mode relative addressing.
In addition to the addressing modes we have already discussed, our letter carrier must understand a whole set of instructions. For instance, the carrier must check to see if the postage has been put on each envelope. We don't have to specify that the letter carrier does this: this function is implied by the instruction. There are several implied addressing modes in the 6502 Building, as we shall see.
This example has shown what addressing modes are, and why there are a number of different modes available to make the task of addressing easier. Let's now leave our building, get back to our ATARIs, and discuss the various addressing modes available in the 6502.
MEMORY ADDRESSING MODES OF THE 6502
The 6502 microprocessor can address memory in 13 different ways, and we'll examine each of these now. For the first eight of these addressing modes, we'll use the LDA instruction discussed in Chapter 4, although many of the other instructions can also utilize these addressing modes. See Appendix 1 for details.
The first addressing mode is called the immediate mode, and specifies that we want to load the accumulator with the number which follows. For example,
tells the computer to load the accumulator with the number $4F, or decimal 79. The same instruction could be written like this:
Having multiple numbering systems available doesn't make things harder, just more versatile.
Note that any instruction written in the immediate addressing mode will result in 2 bytes of machine language code, 1 for the instruction and 1 for the number. Furthermore, we cannot specify a number larger than 255, since this is the largest number that can be coded in 1 byte. The 6502 is an 8-bit microcomputer, and now you know what that means – only 1 byte (8 bits) can be operated on at one time. A 16-bit microcomputer can load and operate on numbers up to 65,536, since this is the largest number which can be coded in 2 bytes (16 bits).
One further concept which can be covered here is the length of time it takes the computer to complete each instruction. We refer to this in terms of the number of cycles the instruction takes to execute. One cycle is the shortest time period the computer deals with, and the 6502A in your ATARI has a cycle time of 560 nanoseconds. That's 0.00000056 seconds! The immediate mode LDA instruction we just discussed requires 2 cycles to execute, or 0.00000112 seconds. That's about one microsecond! Now you can begin to see how fast your ATARI can really be.
The second addressing mode we'll discuss is the absolute mode, used when you want to load the accumulator from a specific, known memory address. The form of the command is:
which tells the computer to load the accumulator from memory location decimal 315. As for the immediate mode discussed above, the same instruction could have been written like this:
If memory location 315 contains the value 243, for example, then the accumulator will also contain the value 243 following the execution of this statement. Note that LDA does not change the value stored in memory location 315; it just copies what was there into the accumulator. It's just like this BASIC statement:
Here we copy the contents of memory location 315 into the variable called A. Location 315 is unchanged following either the assembly language or BASIC instruction.
The absolute addressing mode produces 3 bytes of machine language code, since this instruction must be able to load the accumulator from anywhere in memory. That is, to code for any address above 255 requires 2 bytes, and we also need 1 byte for the instruction. By the way, the 6502 family of microprocessors addresses memory in low byte-high byte order, the reverse of some other popular microprocessors. For example, take the following instruction:
When this assembly language instruction is assembled – translated into machine language by an assembler – the code for LDA in the absolute addressing mode, $AD, comes first, and the address comes next, in low-high order:
LDA $2F3C becomes AD3C2F
Reading printouts of assembler output can sometimes be confusing, but after a little practice, it will seem natural to you.
ZERO PAGE MODE
The next addressing mode that we'll discuss is called the zero page mode. This mode is used to load the accumulator from an address in the first 256 bytes of memory, page zero. Since no address on this page can be more than 1 byte long, the zero page absolute addressing system requires only 2 bytes, 1 for the instruction, and 1 for the address. For example,
which could be written
tells the computer that the programmer wants to load the accumulator from an address which is on page zero. This instruction will be coded appropriately by any assembler. It is of interest to learn that the zero page addressing mode requires only 3 cycles to execute, in contrast to 4 for the absolute addressing mode. Therefore, in a program which requires maximum speed, assembly language programmers use page zero whenever possible. But remember that very few such locations are available under most conditions in your ATARI. If either the BASIC or Assembler/Editor cartridges is in place in your ATARI, only six page zero locations are available for use by an assembly language program. Having only six page zero locations sounds very hard to deal with, but some other popular microcomputers leave only two available, so we have a virtual embarassment of riches in the ATARI!
ZERO PAGE INDEXED MODE
The next addressing mode we'll discuss is called the zero page indexed, or the zero page, X mode, and is the first addressing mode to be discussed that uses the X register as an offset register for addressing. In this addressing mode, the value the X register has at the moment the instruction is encountered is added to the value of the specified address in order to arrive at the final address to be used. As an example, suppose the X register has the value 5 stored in it, and we encounter this instruction:
We already know that the first part of this instruction, if seen by itself, would mean to load the accumulator from the hexadecimal address $43, on page zero. To arrive at the correct loading address in this case, we simply add 5, the value contained in the X register, to the base address $43 specified in the instruction, and arrive at the hexadecimal address $48. Therefore, this instruction currently means to load the accumulator from the hexadecimal address $43 + 5, or $48.
Note the use of the word currently. This addressing mode is the first we have encountered in which an instruction does not always mean the same thing each time we see it. For instance, the X register might contain the value 2 when we encounter the same instruction:
Now we would not load from hexadecimal address $48, but rather from $45 ($43 + 2 = $45).
It should be apparent that if we first retrieve a value from one zero page address and then want to retrieve a value from the next higher zero page address, by using this zero page, X addressing mode we could increase either the base address or the X register. That is, we could keep the value stored in the X register at 2 by writing this:
Or we could increase the value stored in the X register to 3, by writing this:
These two examples seem trivial, and you may well ask what difference it could possibly make to prefer one mode over another; but we shall see later that the second method, increasing the X register and keeping the instruction constant, is vastly preferable for several reasons. For now, it is enough to realize that there are several ways to accomplish the same end, and that one may be the best way, even if we are not yet sure why.
The zero page, X addressing mode requires only 2 bytes when converted to machine language and requires 4 machine cycles to execute. It is therefore slightly slower than the direct zero page addressing mode, which requires only 3 machine cycles. This sacrifice in speed is the price paid for the versatility and power gained. Of course, in applications which require pure speed, it may be necessary to take this slightly slower execution time into account, or to sacrifice the power of this instruction and use only zero page addressing.
THE ABSOLUTE INDEXED MODES
The next two addressing modes are so similar that they will be discussed together. They are relatives of the mode just discussed, but they are applicable to any address in the computer, not just zero page addresses. These are the absolute, X and absolute, Y addressing modes, often referred to as absolute indexed addressing modes. They work by adding the contents of the X or the Y register, respectively, to the base address referred to in the instruction. For instance, if the X register contains the value 3, then the instruction
loads the accumulator from memory location $0345, since $0342 + 3 = $0345. In an analogous fashion, if the Y register contains the value 4, then the instruction
loads the accumulator from memory location $034B, since $0347 + 4 = $034B.
Since we need to address the entire memory space of the computer with these two instructions, they are both 3-byte instructions. They each require 4 machine cycles to execute, which is very interesting to us, since an absolute LDA instruction also requires 4 machine cycles to execute. Here's a case in which we're getting something for nothing – increased power and versatility at no increase in execution speed! Well, almost no increase. You knew there had to be a catch somewhere. Here's the problem. In the case where the base address plus the offset add together to produce an address on a page higher than that referred to by the base address, the 6502 requires 1 more machine cycle to correct for this. For example, suppose the value in the X register is 4, and we encounter this instruction:
The base address in this example is located on page 5; in fact, it is the last address on page 5. The offset, 4, if added to this address, results in the value $0603, so this instruction means to load the accumulator from memory location $0603. However, we can see that this location is on page 6, and the base address is on page 5. Although the 6502 can handle this problem, it takes somewhat longer – in fact, 1 cycle longer – to correct for this crossing of a page boundary. Any addressing modes in the 6502 which involve crossing such a page boundary require 1 extra cycle to execute. In general, this should not be a problem, and the computer will take care of it for us; but in cases where precise timing is critical, the programmer should be aware of such situations and make provisions for the extra time these instructions will require.
TWO INDIRECT MODES
The last two methods of addressing which will be illustrated using the LDA instruction are both indirect addressing systems. These two systems are frequently confused because their names are so similar, but their uses are quite distinct. We will find ourselves using one quite frequently and the other hardly at all. The first is called indirect indexed addressing, and here is the form of its operation:
The parentheses in this instruction indicate that this is an indirect addressing mode. The instruction can be interpreted as follows:
1. On page zero, in locations $43 and $44, find a 2-byte value stored.
2. Interpret this 2-byte value as an address in memory.
3. To this address, add the offset value contained in the Y register. This sum is the address to access for this operation.
4. Load the accumulator from this calculated address.
Whew! Seems pretty complicated, doesn't it? Let's take a simple example and work our way through it slowly.
First, let's assume that we have stored the value #$53 (this is the hexadecimal number 53, remember?) in memory location $43 and the value #$E4 in memory location $44. Furthermore, let's assume that the Y register contains the value 6. Pictorially, this is the situation:
Now we encounter the instruction
The 6502 first looks at memory locations $43 and $44 and takes the values stored there as an address. In this example, it finds the values #$53 and #$E4, and, since it knows the first byte is the low value of the address, and the second is the high value, it realizes that the address referred to is $E453. The 6502 then adds the offset value, 6, obtained from the Y register, to this address, and calculates the address to be accessed to be $E453 + 6 = $E459. Finally, it executes the LDA instruction, and loads the accumulator from memory location $E459.
Although this seems like an extremely cumbersome and complicated way of calculating an address, we shall see how important and versatile this instruction really is. In fact, many applications we will use would not be easy without this addressing mode.
Since the indirect indexed addressing mode requires page zero, it utilizes only 2 bytes for the instruction. However, the calculations involved are fairly complicated, as we have seen, so this addressing mode requires 5 machine cycles to execute.
The last addressing mode to be discussed here is called the indexed indirect mode, and we can immediately see why it is often confused with the mode just discussed, the indirect indexed mode. However, its use is completely different. A typical instruction written in this mode follows:
We can see that this mode uses the X, rather than the Y register, and that the entire operand is enclosed within parentheses. This instruction would be interpreted by the 6502 as follows:
1. Add the value stored in the X register to the base address, $43 (e.g., if X = 4, then this sum equals $47).
2. This sum is then interpreted as another zero page address (in this example, the second zero page address is $47).
3. Find the 2-byte value stored at this calculated address ($47,$48) and interpret it as a new address (see below for a discussion of an example).
4. Load the accumulator from this new address.
Again, let's take an example. We'll assume that we have previously stored the value #$E4 in memory location $48, the value #$53 in memory location $47, and the value 4 in the X register. Pictorially, we have this:
Then we encounter this instruction:
We add the contents of the X register to the base address specified and obtain $43 + 4 = $47. We then look in memory locations $47 and $48, and interpret the 2 bytes there as a new address, $E453 (remember, low byte first and then high byte). Finally, we execute the instruction, loading the accumulator from memory location $E453. This operation requires 6 machine cycles and is therefore the slowest instruction we have yet encountered. Since it requires zero page addressing, it needs only 2 bytes per instruction. As was mentioned above, this instruction is seldom used. Its primary use is for establishing a table on page zero and then accessing this table to provide addresses elsewhere in memory. However, your ATARI has limited zero page space available for your use, especially when either the BASIC or Assembler/Editor cartridge is in place; we generally don't have room to construct such a table on page zero, and we use other addressing modes to construct such tables elsewhere. This mode can be used, however, in applications not designed for use with a cartridge. Arcade-type games are one example: the game stands alone, and you are relatively free to use more of page zero for your own use.
OTHER ADDRESSING MODES
We have now discussed 8 of the 13 available addressing modes of the 6502. The remaining five modes cannot be demonstrated using the LDA command, since it uses only these eight modes. We will now discuss the others, using other commands in the instruction set.
The ROTATE and SHIFT instructions, ROR, ROL, ASL, and LSR, can all use an addressing mode known as accumulator mode:
This simply means that the rotation or shift is to be performed on the contents of the accumulator rather than the contents of some memory location. Note that these instructions can also operate on memory:
Many of the instructions can use an implied mode of addressing, where the addressing mode is obvious from the instruction. For instance, DEX and CLD are both 1-byte instructions whose addressing target is obvious from the instruction itself.
The BRANCH instructions all use the relative addressing mode. That is, one can read the branch as meaning either to branch forward 10 bytes, or to branch backward 4 bytes. The branch is relative to the current position of the program counter.
The JMP instruction can use the indirect form of addressing. For example, if we set up an address by storing #$53 in location $CD and #$E4 in location $CC, we can jump indirectly to $E453:
ZERO PAGE, Y MODE
The final form of addressing is called the zero page, Y form. This second zero page indexed mode is used only by two instructions, LDX and STX. That is, when the X register is used to load or store a value, it may be indexed with the Y register from a zero page base address. This is virtually identical to the zero page, X mode we have already discussed.
This concludes our review of the addressing modes available using the 6502. In later chapters, we will see how these modes can be used to accomplish useful programming chores, and the benefits of having more than just one or two addressing modes will become obvious.
Return to Table of Contents | Previous Chapter | Next Chapter