Addressing Modes Notes With Examples
Addressing Modes Notes With Examples
• a constant;
• a register;
• a memory location.
Before considering in some detail the basic addressing modes, let us recall
that we have already discussed about this topic (even though not in terms
of addressing modes) when we approached the n-address machine subject.
Using examples, we saw that the operand can be in a register (we call this
to be the register addressing mode) or fully included in the instruction
(we call this direct addressing mode), and we tried to figure out the
impact over the code length and execution speed. We also discussed about
the PC-relative addressing and the use of displacements.
The most used addressing modes are presented below; a left arrow means
assignment, and M stands for memory. We use an array notation for
memory because we can view the memory as an array of bytes (or half-
words or words whichever you prefer, but the significance of the notation
must be very clear).
Register
Direct
ex: ADD r1, r2, (100)
means: r1 r2 + M[100]
comment: used to access static data; the address of the operand is include
in the instruction; space must be provided to accommodate a
whole address.
Displacement
Indexed
Autoincrement
Autodecrement
This list is far from being complete and you may wonder:
Rewrite the following sequence of code using the register and register
deferred addressing modes:
/* a sequence that does nothing */
LOAD r1, (200)
ADD r3, r2, 10(r1)
AND r3, r2, @r2
...
...
...
Answer:
LOAD r1, 200# immediate;
LOAD r1, (r1)# register deferred
ADD r4, r2, 10# these two instructions replace the
ADD r3, r2, r4# ADD in the above sequence
LOAD r4, (r2)# and the two simulate the memory
AND r3, r2,(r4)# deferred addressing;
• arithmetic operations:
LOAD r1, 3
• if the instruction size is fixed, a word (32 bit) for instance, then we
must compromise between the space we allocate for immediate
operands and the space we have to use for other fields (opcode,
registers, etc.)
Answer:
LOAD r1, 100# in r1 base
LOAD r2, 0(r1)# load the first element of array
ADD r2, r2, 1
STORE 0(r1), r2
LOADr2, 4(r1)# second word starts at 104
ADDr2, r2, 1
STORE 4(r1),r2
ptr = #
assigns the address of num to ptr. The logical structure created by the
above assignment is:
ptr num
Answer:
The relation between the pointer and the number is shown below:
the integer
200
Answer:
ADD r1, r2, r3
require only one memory access, reading the instruction;
ADD r1, r2, (r3)
require two memory accesses, the first to read the instruction and the other
one to read the value from memory location(s), whose address is in r3;
ADD r1, r2, @(r3)
three memory accesses are made in this case, the first to read the
instruction, the second to get M[r3], and the third one to get M[M[r3]].
While the implementation of this addressing mode has nothing difficult per
se, it raises some problems when we try to realize an efficient
implementation of the CPU: efficient pipelining require all instructions to
complete in the same number of clock cycles, which is difficult if we allow
instructions with different running times. Sure we could make all
instructions execute in the same number of clock cycles as the longest
running instruction, by simply inserting idle clock cycles. What an idea!
It’s wrong because it happens that the longest running instructions are not
the common cases. And it is precisely the common case that we want to
optimize.
Answer:
LOAD r1, 100 # in r1 base;
LOAD r2, 0 # the first index in array;
LOAD r3, 1
ADD r4, r3, (r1)[r2]
STORE (r1)[r2]
ADD r2, r2, 1 #index = index + 1
ADD r4, r3, (r1)[r2]
STORE (r1)[r2]
What is the price we have to pay to include this addressing mode in the
instruction set? Again we take into account how the addressing mode
effects the instruction length and the execution time as compared with
other addressing modes. We shall consider the instruction encoding and the
execution time as the parameters for this discussion.
Instruction encoding
For a three address machine (our examples so far are for such a machine)
we need four fields to encode the registers to be used:
• destination
• first source operand
• base
• index
For a 32 bit machine with fixed instruction size (one word), and a set of 32
registers, the necessary fields to encode the four registers require 4*5 = 20
bits. If we allow 6 bits for the opcode, then we still have 32 - (20+6) = 6
bits in the instruction. Do we need them? Of course we need them because
we have to encode two more things in the instruction:
• what kind of addressing mode are we using;
• what is the dimension size with which the index has to be
multiplied.
As long as we are concerned with the first problem we face yet another
• byte;
• half-word;
• word;
• double-word.
Certainly these two bits are needed, it would be much too restrictive not to
allow certain arrays of the basic data types. By now the following bits are
available:
32 - (20 + 6) - 2 = 4 bits
four bits with which we can try to encode the addressing mode and,
possibly, the operand to which it applies. A possible solution could be to
use two bits for encoding the addressing mode, thus allowing four
addressing modes, and the other two to specify to which of the three
operands applies. Should we allow more addressing modes, so we restrict
the number of operands to which that mode applies.
Execution time
Answer:
While the shift hardware is simpler than that required for a full integer
multiplier, it still is an expensive resource (in terms of silicon area), and
will probably be introduced in the CPU only if the shift operation is a must.
Note that though most CPUs introduced in the recent years have shifters as
a part of the CPU, shift instructions are common in the instruction sets.
Answer:
LOAD r1, 100# the base
LOAD r2, 1 # 1 will be used for increment
ADD r3, r2, (r1)
STORE (r1), r3
ADD r1, r1, 4# the next array element is at 104
ADD r3, r2, (r1)
STORE (r1), r3