ADDRESSING MODES

Back when a full 3-hour course on assembly language programming was a part of the curriculum, approximately one-third of the course was devoted to the intricacies of addressing modes. In this class, we will spend considerably less time on them. An addressing mode is simply a way of specifying an operand.

Absolute addressing. The address that is specified in the instruction is the actual address of the operand. Absolute addressing was the mode used by MARIE. Although this may seem like the obvious way to specify an operand, it has several shortcomings:

EXAMPLE

Assume that the op code for a "move byte" instruction is 0000 0010 (02 in hex). Assume that we want to move data from location 5 to location 6 using absolute addressing on a machine with 32-bit addresses. The 5 is 0000 0000 0000 0000 0000 0000 0000 0101 (00 00 00 05 in hex) and the 6 is 0000 0000 0000 0000 0000 0000 0000 0110 (00 00 00 06 in hex). It would seem that the complete instruction (in hex) would be 02 00 00 00 05 00 00 00 06. And this would work if there were only one addressing mode. However, since there is more than one addressing mode (more than one way to interpret the operand bits in the instruction), we need to also tell which addressing mode is being used (for each operand). Assume that one byte is used to specify the addressing mode for each operand. And assume that absolute addressing mode is mode number 1 (01 in hex). Our instruction now becomes: 02 01 00 00 00 05 01 00 00 00 06, where the bold underlined part of each operand is used to specify the addressing mode.

Because of the problems with absolute addressing, computer designers have developed other addressing modes.


REGISTER ADDRESSING

Since data must be loaded into registers before any processing can be done on it, we must have a way of specifying which register we wish to use. Three bits in an instruction can specify one of eight registers. Four bits can specify one of 16 registers. "n" bits can specify one of 2n registers. This is the reason that the number of registers in a CPU is always a power of two.

EXAMPLE

Assume that we have a CPU with 16 registers. Also assume that register addressing mode is mode number 2. To move a byte (op code is 02 in hex) from register 9 (09 in hex) to register 10 (0A in hex), our instruction would look like this: 02 02 09 02 0A, where the blue number is the op code, the green number is the first operand (register 09), and the red number is the second operand (register 0A).


 

BASE REGISTER AND RELATIVE ADDRESSING

These two addressing modes are similar in that they both specify an offset that is to be added to a register. When the offset is added to the address in the register, the result is the address of the operand. The only difference between the two methods is that with base register addressing, the base register must be specified as part of the operand, and with relative addressing, the "base register" is the program counter.

EXAMPLE: Base register (mode 03)

Assume that the contents of the base register (we'll use register 8) is 00 00 01 00 (hex). And assume that we want to move a byte (op code is 02 in hex) from location 00 00 01 05 (an offset of 5 bytes from the address in the base register) to 00 00 01 06 (an offset of 6 bytes from the address in the base register). Also assume that base register addressing mode is mode number 3. With base register addressing, it is not enough to know the addressing mode. The base register must also be specified. We will use one byte to specify the addressing mode (03) and another byte to specify the base register (08) for each operand. Our final assumption is that the offset is stored as a 16-bit number. Our instruction will look like this: 02 03 08 00 05 03 08 00 06 where the blue number is the op code, the green number is the first operand (the bold underlined part is the addressing mode specifier) and the red number is the second operand.

EXAMPLE: Relative addressing (mode 04)

Assume that the byte we want to move is 100 (hex) bytes beyond the current instruction. This amount can be added to the PC to get the correct address. In this case, we are using the PC as a base register. This may be a separate mode. Assume mode 04. Since the PC is implied in relative addressing mode, we do not need to specify a register – only the mode -- relative addressing. Again we will assume that our offset can be stored in a 16-bit number. Let's assume that we want to move a byte from 100 bytes past the PC to register 5. Our instruction will look like this: 02 04 01 00 02 05

---

 

IMMEDIATE ADDRESSING (mode 05)

Sometimes, it would be convenient for an operand to be part of the instruction itself. This means that the operand would have to be a constant. When the operand is a part of the instruction itself, the addressing mode is called "immediate" mode (because the operand is available immediately -- it's part of the instruction -- you don't have to go back to memory to fetch it).

EXAMPLE

Assume that we want to move (op code is 02) a 3 into register 7. And assume that immediate addressing mode is mode number 5 (05). And assume that immediate operands occupy one byte. Our instruction will look like this: 02 05 03 02 07 where the blue number is the op code, the green number is the first operand (an immediate 3), and the red number is the second operand (register 7).


INDIRECT ADDRESSING (mode 06)

Direct addressing is simple: the address of the operand is specified in the instruction. With indirect addressing, the address of the address is specified in the instruction.

EXAMPLE

Assume that we want to move (op code 02) the number at location 00 00 02 00 into register 7. And assume that indirect addressing mode is mode number 6 (06). Also, assume that the address 00 00 02 00 is stored in location 00 00 12 34. Using direct addressing, the instruction would look like this: 02 01 00 00 02 00 02 07 However, with indirect addressing, the instruction would look like this: 02 06 00 00 12 34 02 07 where the blue number is the op code, the green number is the first operand (06 = indirect, so go to location 00 00 12 34, not for the data as with direct addressing, but for the address of the data: 00 00 02 00), and the red number is the second operand (register 7).

 

 

REGISTER INDIRECT ADDRESSING (mode 07)

This is exactly the same as indirect addressing, except that the address of the operand is in a register rather than in a memory location.

EXAMPLE

Assume that, like the previous example, we want to move (op code 02) the number at location 00 00 02 00 into register 7. And assume that register indirect addressing mode is mode number 7 (07). Also assume that the address 00 00 02 00 is stored in register 12 (0C). Our instruction will look like this: 02 07 0C 02 07 where the blue number is the op code, the green number is the first operand (07 = register indirect, and 0C is the register number), and the red number is the second operand (register 7).


INDEXED ADDRESSING (mode 08)

You are already familiar with the idea of indexing, except that you probably called it subscripting. In a high-level language, indexing looks like this:

     for i= 1 to 10 do
        writeln (list[i]);

Because actual subscripts are impossible to do on punched cards or computer terminals (and before the advent of the bit-mapped graphics displays that are common today), instead of writing listi, we wrote list[i], instead. The code above will print out the items numbered 1 through 10 of an array named "list". Because an array is such a common data structure, many CPU's have an indexed addressing mode that makes it easier for the machine/assembly language programmer to step through an array. Such an addressing mode will use an index register. The value in the index register is added to another base address to determine the actual address of the data.

EXAMPLE

Assume that indexed addressing mode is mode 8 (08). Assume that we have an array starting at location 00 00 01 00. Also assume that the index register is register 10 (0A), and that it currently holds the value 3 (note that because the 3 is an offset, it will actually refer to the fourth item in the array). To move the fourth byte in the array into register 7, our instruction would look like this: 02 08 0A 01 00 00 01 00 02 07. Note that, to do indexed addressing, two addressing modes must be combined. In addition to the indexed addressing mode (the light green part of the first operand), a base address must be specified (the dark green part of the first operand). This instruction is executed as follows: the 02 means "move byte"; the 07 0A means use register 10 (0A) as an index into the array whose base address follows; the base address is 00 00 01 00 (direct addressing); and the destination is register 7.


AUTOINDEX (AUTOINCREMENT, AUTODECREMENT) (09, 0A)

Autoincrement and autodecrement are identical to indexed addressing mode except that the index gets automatically incremented (or decremented) each time you use it in a loop (just like the "for" loop in most high-level languages).


INDIRECT INDEXED AND INDEXED INDIRECT ADDRESSING

This sounds a little too hairy to go into much detail. It can be used to step through an array of pointers (addresses) such as a parameter list.