<<

Chapter 11

Addressing Modes

11–1 Register addressing mode is the most efficient addressing mode because the operands are in the itself (there is no need to access memory).

11–2 Immediate addressing mode can be used to specify constants; thus, it cannot be used to specify the destination operand of an instruction.

11–3 Operand specified by the immediate addressing mode is part of the instruction and therefore is in the code segment.

11–4 Note that to locate a data item in a data segment, we need to specify two components: the data segment base address and an offset value within the segment. In direct addressing mode, the offset is specified directly as part of the instruction. This addressing mode is the simplest of all the memory addressing modes.

The direct addressing can be used to access simple variables. The main drawback of this addressing mode is that it is not useful for accessing complex data structures such as arrays and records that are used in high-level languages.

The indirect addressing mode remedies this deficiency. In this addressing mode, offset of the data is in one of the general registers. For this reason, this addressing mode is sometimes called the register indirect addressing mode. For 16- segments, only BX, BP, SI, and DI registers are allowed to hold the offset. The 16-bit memory addressing modes supported are shown in the following figure:

1 2 Chapter 11

Memory

Direct Indirect [disp]

Register Indirect Based Indexed Based-Indexed [BX] [BP] [SI] [DI] [BX + disp] [SI + disp] [BP + disp] [DI + disp] Based-Indexed Based-Indexed with no displacement with displacement [BX + SI] [BP + SI] [BX + SI + disp] [BX + DI] [BP + DI] [BX + DI + disp] [BP + SI + disp] [BP + DI + disp]

11–5 The Pentium supports a more flexible set of memory addressing modes for 32-bit addresses (shown in the following figure).

Addressing Modes

Register Immediate Memory

Direct Indirect [disp]

Register IndirectBased Indexed Based-Indexed [Base] [Base + disp] [(Index * scale) + disp]

Based-Indexed Based-Indexed with no scale factor with scale factor [Base + Index + disp] [Base + (Index * scale) + disp]

As shown in this figure, for 32-bit segments, all eight 32-bit registers (i.e., EAX, EBX, ECX, EDX, ESI, EDI, EBP, and ESP) can be used. A summary of these memory addressing modes is given below:

Segment + Base + (Index * Scale) + displacement

CS EAX EAX 1 No displacement SS EBX EBX 2 8-bit displacement DS ECX ECX 4 32-bit displacement ES EDX EDX 8 FS ESI ESI GS EDI EDI Chapter 11 3

EBP EBP ESP

11–6 Segment override prefix is necessary to assign non-default segment association. For example, if the offset in BX refers to a data item on the stack, we need to use segment override to specify this fact as shown below:

add AX,SS:[BX]

We can use this code to access a data item from the stack whose offset relative to the SS register is given in the BX register. Similarly, the BP register can be used as an offset into the data segment by

add AX,DS:[BP]

The CS, ES, FS, and GS segment registers can also be used to override the default association, even though the CS register is not used frequently.

11–7 Operand override prefix is necessary when 16- and 32-bit operands are mixed in a program. When the default is 16-bit operands, if we use a 32-bit operand, as in

mov EAX,123

the following code is generated by the assembler:

66 | B8 0000007B

The assembler automatically inserts the operand size override prefix (66H).

11–8 Address size override prefix is necessary when mixed address sizes are used in a program. The greatest benefit of the address size override prefix is that we can use all the addressing modes provided for 32-bit addresses in the 16-bit addressing modes. For instance, we can use a scale factor, as in the following example:

mov AX,[EBX+ESI*2]

The assembler automatically inserts the address size override prefix (67H) as shown below:

67|8B0473

11–9 Real mode: No difference. Protected mode: Indexed addressing allows the scale factor, which is useful in accessing arrays of element size 2, 4, and 8 bytes.

11–10 Based-indexed addressing is more flexible as it allows us to use two registers (a base register and an ) to specify the effective address. This facilitates, for example, in accessing two-dimensional arrays, arrays of records, etc. 4 Chapter 11

11–11 The code is shown below: mov SI, 8 ; SI = displacement of 5th element ; (i.e., table1[4] in ) mov AX,table1[SI] cmp AX,table1[SI-2]; compare 5th and 4th elements

11–12 In row-major ordering, arrays are stored row-by-row whereas in the column-major ordering, the

layout is column-by-column as shown in the following figure (for a 4¢4 matrix class_marks):

High memory High memory class_marks[4,2] class_marks[4,2] class_marks[4,1] class_marks[3,2] class_marks[4,0] class_marks[2,2] class_marks[3,2] class_marks[1,2] class_marks[3,1] class_marks[0,2] class_marks[3,0] class_marks[4,1] class_marks[2,2] class_marks[3,1] class_marks[2,1] class_marks[2,1] class_marks[2,0] class_marks[1,1] class_marks[1,2] class_marks[0,1] class_marks[1,1] class_marks[4,0] class_marks[1,0] class_marks[3,0] class_marks[0,2] class_marks[2,0] class_marks[0,1] class_marks[1,0]

class_marks class_marks[0,0] class_marks class_marks[0,0] Low memory Low memory (a) Row-major order (b) Column-major order

11–13 High-level languages provide data structures for multidimensional arrays. However, does not provide such facilities. Therefore, it is necessary to specify a pointer to the element you want to access. Obviously, to do this, you need to know how the data is stored. 11–14 Row-major order as the program specifies the values row-by-row and the assembler uses the same order to allocate storage. 11–15 The following stores class_marks in column-major order: Chapter 11 5

class_marks DW 90,79,70,60,51 DW 89,66,60,55,59 DW 99,70,77,68,57

11–16 Displacement in bytes = (j * ROWS + i) * ELEMENT_SIZE where ROWS is the number of rows and ELEMENT_SIZE is the size of each element in bytes.

11–17 Assume that X and Y are the low subscripts for the first and second dimensions, respectively. We can modify the formula given on page 451 as Displacement in bytes = ((i - X) * COLUMNS + (j - Y)) * ELEMENT_SIZE where COLUMNS is the number of columns in the array and ELEMENT_SIZE is the number of bytes required to store an element.