Addressing Modes: Creating An Effective Address
Addressing Modes: Creating An Effective Address
Addressing Modes: Creating An Effective Address
The power of any instruction set is a function of both the types of instructions implemented and
the number of addressing modes available. Suppose that a microprocessor could not directly
manipulate data in a memory location. The data would have to be loaded into a processor
register, manipulated, and written back into memory. If an addressing mode were available that
could directly operate on data in memory, the task could be done more effectively. In this
section we will examine the many different addressing modes available in the 80x86, and see
how each is used. The examples presented make use of the MOV instruction, which has the
following syntax: MOV DESTINATION,SOURCE. It will be obvious in the examples what
is being accomplished with each MOV instruction, so a detailed description is not included
here. Also, whenever the contents of a memory location or an address or data register is
referred to, assume that the value or address is hexadecimal.
Register Addressing
The operand field of an instruction in many cases will contain one or more of the CPU's
internal registers. Register addressing is the name we use to refer to operands that contain one
of these registers. The MOV DS,AX instruction is an example of register addressing, as we are
only using processor registers in the operand field. Instructions of this form often execute very
quickly, because they do not require any memory accesses beyond the initial instruction fetch
cycles. The machine code corresponding to MOV DS,AX is 8E 08, a 2-byte instruction
containing the information necessary to perform the desired operation. DEC DX (decrement the
DX register) is another example of register addressing, and has 4A as its corresponding
machine code.
If register AX contains the value 1000H and register BL contains 80H, what is the result of
MOV AL,BL
Solution: The contents of the BL register are copied into the AL register, leaving AH
undisturbed. The final value in AX is 1080H. Notice that the contents are copied during the
MOV. MOV should also be interpreted as make a copy of. Since the source data is not
destroyed when we move data from one place to another, we are merely making a copy of the
source data.
The machine code for MOV AL,BL is 88 D8.
Immediate Addressing
We often use immediate data in the operand field of an instruction. Immediate data represents a
constant that we wish to place somewhere, by MOVing it into a register or a memory location.
In MOV AX,1000H, we are placing the immediate value 1000H into register AX. Immediate
data is represented by 8-bit or 16-bit numbers that are coded directly into the instruction. For
example, MOV AX,1000H is coded as B8 00 10, and MOV AL,7 is coded as B0 07. Notice in
the first instruction that the 16-bit value l000H has its lower byte (00) and its upper byte (10)
reversed in the actual machine code. This technique is commonly referred to as Intel byte-
swapping, and it is the way all 16-bit numbers are stored.
An important question at this time is “How did the assembler know that the 7 in MOV AL,7
should be coded as the single byte value 07, and not the 2-byte value 07 00 (in byte-swapped
form)?” The answer is that the assembler looked at the size of the other operand in the
instruction (AL). Because AL is the lower half of the AX register, the assembler knows that it
may contain only 8 bits of data. Knowing this, we should see why MOV AL,9C8H would be an
illegal instruction. If you cannot answer this question, think about how many bits are needed to
represent the hexadecimal number 9C8. Because 12 bits are needed, we cannot possibly store
9C8H in the 8-bit AL register.
What is the result of
MOV CX,7
Solution: Because register CX is specified, the immediate value 7 is coded as the 2 byte
number 00 07. One exception is when the operand was defined as an Equate. Equates are
defined as a 16-bit value. Consider the following:
value equ 15
mov al,value
mov bh,value
mov cx,value
All the above are valid instructions. In the case of the first two instructions, only the low byte
of the operand is copied into the register.
Had value been DB instead of EQU, the last instruction would be invalid.
Direct Addressing
In this addressing mode the effective address is formed by the addition of a segment register
and a displacement value that is coded directly into the instruction. The displacement is usually
the address of a memory location within a specific segment. One way to refer to a memory
location in the operand field is to surround the memory address with square brackets. The
instruction MOV [7000H],AX illustrates this concept. The 7000H is not thought of as
immediate data here, but rather as address 7000H within the segment pointed to by the DS
register. DS is the segment register used whenever SQUARE brackets [ ] are used in the
operand field (unless we override the use of DS by specifying a different segment register). The
effective address is DS:1000H
What is the result of
MOV [7000H],AX
Assume that the DS register contains 1000H, and AX contains l234H.
Solution: Remember that when the CPU uses a segment register to form an effective address, it
shifts the segment register 4 bits to the left (turning 1000H into 10000H) and then adds the
specified 16-bit displacement (or offset). Thus, the effective address generated by the processor
is 17000H. Because register AX is used in the operand field, two bytes will be written into
memory, with the lower byte (34) going into the first location (17000H) and the upper byte (12)
going into the second location (17001H). Once again, we can see that the processor has byte-
swapped the data as it was written into memory.
The machine code for MOV [7000H],AX is A3 00 70.
Another form of direct addressing requires the use of a label in the operand field. The
programmer can override the automatic use of the DS register for memory accesses by
specifying a different segment register within the operand field. If we wish to use the extra
segment register in the instruction, we would write MOV ES:[7000H],AX. The machine code
required to allow the use of the ES register in this instruction is 26 A3 0070.
Based Addressing
This addressing mode uses one of the two base registers (EX or HP) as the pointer to the
desired memory location. It is very similar to register indirect addressing, the difference being
that an 8or 16-bit displacement may be included in the operand field. This displacement is also
added to the appropriate segment register, along with the base register, to generate the effective
address. The displacement is interpreted as a signed, 2's complement number. The 8-bit
displacement gives a range of –128 to +127. The 16-bit displacement gives a range of -32768 to
32767. So, the signed displacement allows us to point forward and backward in memory, a
handy tool when accessing data tables stored in memory.
What is the effective address generated by the instruction
MOV AX, [BX+4]
Assume that the DS register contains 100H and register BX contains 600H.
Solution: The DS register; the BX register, and the displacement value are added together to
create the effective address 1604H. This address is then used to read the word out of locations
1604H and 1605H into the AX register. The machine code for MOV AX,[BX+4] is 8B 47 04
Indexed Addressing
Like based addressing, indexed addressing a1lows the use of a signed displacement. The
difference is that one of the index registers (SI or DI) must be used in the operand field.
What is the effective address generated by the instruction
MOV [DI-8],BL
Assume that the DS register contains 200H and that register DI contains 30H.
Solution: The negative displacement is combined with the DI register. Notice that although the
DI register points to address 30H within the data segment, the actual location accessed is 8
bytes behind. The machine code for MOV [DI-8],BL is 88 SD F8. As in the previous example,
the third byte in the machine code is the displacement value. In this case, the displacement of -8
is coded as F8 hexadecimal, which is the 2's complement of 8.
Port Addressing
The Intel brand of microprocessors differ from other processors on the market in their
implementation of the use of I/O ports for data communication between the processor and the
outside world. One way to get information into the CPU is to read it from memory. Another
way is to read an input port. When sending data out of the CPU, we can direct it into a memory
location or send it to an output port. The CPU provides the programmer with up to 65,536 input
and output ports (although many useful designs rarely use more than a handful of I/O ports). An
I/O port is accessed in much the same way that memory is accessed, by placing the address of
the I/O port onto the address bus and enabling certain control signals. The address of the I/O
port can be coded directly into an instruction, as in:
IN AH,80H
or
OUT 0B0H,AL
In this case, the port address must be between 0H and 0FFH, a total of 256 different I/O ports.
Notice that the AL register is used to receive the port information. We could also use AX to
receive 16-bits of data from an input port.
A second method of addressing I/O ports requires that the port address be placed into the DX
register. The corresponding instructions are:
IN AL,DX
OUT DX,AL
Since we are now using the DX register to store the port address, our choices range from 0H to
0FFFFH, a total of 65,536 I/O locations. I/O ports are very useful for communication with
peripherals connected to the CPU, such as serial and parallel I/O devices, video display chips,
clock/calendar chips, and many others.