CIS-77 Home http://www.c-jump.com/CIS77/CIS77syllabus.htm
Like direct memory operands, indirect memory operands specify the contents of a given address.
However, the processor calculates the address at run time by referring to the contents of registers.
Since values in the registers can change at run time, indirect memory operands provide dynamic access to memory.
Indirect memory operands make possible run-time operations such as pointer indirection and dynamic indexing of array elements, including indexing of multidimensional arrays.
For example, the following instruction moves into AX the word value found at the address in DS:BX.
mov ax, WORD PTR [bx]
where
WORD specifies the data size
PTR re-casts memory location pointed by [BX] into the WORD-sized value.
When you specify more than one register, the processor adds the contents of the two addresses together to determine the effective address (the address of the data to operate on):
mov ax, [bx+si]
Address displacement is a constant value added to the effective address.
A direct memory specifier is the most common type of displacement:
table WORD 100 DUP (0) . . . mov ax, table[ esi ]
In relocatable expression table[ esi ] , the displacement is table, providing the base address of an array
ESI holds an index to an array element. The ESI value is calculated at run time, often in a loop.
Each displacement can be an address or numeric constant.
If there is more than one displacement, the assembler totals them at assembly time and encodes the total displacement.
For example, in the statement
table WORD 100 DUP (0) . . . mov ax, table[bx][di]+6
both table and 6 are displacements.
You must give the size of an indirect memory operand in one of three ways:
By the variable's declared size
With the PTR operator (which acts similar to C-style cast)
Implied by the size of the other operand.
The following lines illustrate all three methods, assuming the size of the table array is WORD, as declared earlier.
table WORD 100 DUP (0) . . . mov table[bx], 0 ; 2 bytes - from size of table mov BYTE PTR table, 0 ; 1 byte - specified by BYTE mov ax, [bx] ; 2 bytes - implied by AX
The assembler allows a variety of syntaxes for indirect memory operands.
However, all registers must be inside brackets.
Each register can be enclosed in its own pair of brackets, or in the same pair of brackets separated by a plus operator (+).
The following variations are legal and assemble the same way:
mov ax, table[bx][di] mov ax, table[di][bx] mov ax, table[bx+di] mov ax, [table+bx+di] mov ax, [bx][di]+table
All of these statements move the value in table indexed by BX+DI into AX.
|
|
In indirect memory addressing the base register identifies which segment register will be used to calculate the actual memory location.
Therefore, we need to understand the rules that define which register is the base register in indirect memory addressing mode.
The default segment register is SS if the base register is EBP or ESP.
However, if EBP is scaled, the processor treats it as an index register with a value relative to DS, not SS.
All other base registers are relative to DS.
If two registers are used, only one can have a scaling factor.
The register with the scaling factor is defined as the index register.
The other register is defined as the base register.
If scaling is not used, the first register is the base.
If only one register is used, it is considered the base for deciding the default segment, unless it is scaled.
The following examples illustrate how to determine the base register:
mov eax, [edx][ebp*4] ; EDX base (not scaled - seg DS) mov eax, [edx*1][ebp] ; EBP base (not scaled - seg SS) mov eax, [edx][ebp] ; EDX base (first - seg DS) mov eax, [ebp][edx] ; EBP base (first - seg SS) mov eax, [ebp] ; EBP base (only - seg SS) mov eax, [ebp*2] ; EBP*2 index (seg DS)
Immediate Mode (memory is not accessed) - operand is part of the instruction. For example, a constant encoded in the instruction:
mov eax,567 mov ah, 09h mov dx, offset Prompt
Register Addressing (memory is not accessed) - operand contained in register:
add ax, bx
Direct Mode (memory accessed once) - operand field of instruction contains address of the operand:
value dword 0 .. add eax, value ; Either notation does the add eax, [value] ; same thing
Assembly code
tbl DW 20 DUP (0) .. mov [tbl], 56
is equivalent to C statement
tbl[ 0 ] = 56; // C code
register indirect addressing (aka indirect addressing mode) often used for addressing data arrays inside programming loops:
Effective address of operand contained in a register.
For 32-bit addressing, all 32-bit registers can be used.
For 16-bit addressing, the offset value can be in one of the three registers: BX, SI, or DI:
mov bx, offset Table ; Load address add ax, [bx] ; Register indirect addressing
Square brackets [ BX ] indicate that BX is holding a memory offset.
Operand [ BX ] serves as a pointer to data in memory.
Register indirect can be used to implement arrays. For example, to sum an array of word-length integers,
mov cx, size ; set up size of Table mov bx, offset Table ; BX <- address of Table xor ax, ax ; zero out Sum Loop1: add ax, [bx] inc bx ; each word is 2 bytes long, so inc bx ; need to increment BX twice! loop Loop1
Indexing: constant base + register.
Fixed Base (address) + Variable Register Offset (operand field contains a constant base)
Effective address is obtained by adding value of operand field to contents of register.
This is known as array type addressing, also called displacement addressing.
mov eax, [ ebx + 5 ] mov eax, [ ebx + esi + 5 ]
There are restrictions on the combinations of registers allowed within the brackets: you can have ESI or EDI, but not both, and you can have EBX or EBP, but not both.
The following instructions are equivalent:
add ax, Table[ bx ] add ax, [ Table + bx ] add ax, Table + [ bx ] add ax, [ bx ] + Table
Indexing With Scaling: Base + Register Offset * Scaling Factor
Operand field contains base address.
Useful for array calculations where size of component is multiple bytes long.
Stack Addressing: PUSH and POP, a variant of register indirect with auto-increment/decrement using the ESP register implicitly.
Jump relative addressing, EIP + offset
Operand field contains a displacement.
Used by near and short jump instructions on the Intel 80x86.
see also:
Effective address calculation times: