..

Data Accessing Methods - Addressing Modes

Working directly with assembly, is fun, but you need to be efficient we should take care of our data access. To tackle this, we need to know about Addressing Modes.

Addressing nodes are techniques to access data from memory and registers. The way this memory in interpreted and used is specified by the chosen addressing mode, and this means flexibility. Flexibility means more options, and more options means more fun.

All the assembly code used here is X86.

Immediate Addressing

We embed our operation directly in the instruction. For example, to move a value to a register, instead to pass an address to read from, we pass the value directly to the register.

Good for small constants or fixed values.

Register Addressing

In this one, the operand is stored in a register, and the instruction refers to that register.

Direct Addressing

We pass the memory address that should be accessed by the instruction. The values in the address are copied to the register.

Indirect Addressing

The instruction specifies a register or memory location that holds the address of the operand.

Indexed Addressing

Uses a base register, and an offset (or displacement) is added to that register to form the final memory address. The offset can be used to access elements in an array or data structure.

Useful for accessing array elements.

How It Works:

A better example:

Assume:

1MOV BX, 2000h    ; Load the base address of the array into BX
2MOV AX, [BX + 4] ; Load the 3rd element (offset = 2 bytes * 2 = 4) into AX

Breakdown:

Base-Indexed Addressing

Combines the base address from a register and an index from another register to determine the effective address.

Useful for complex data structures like multi-dimensional arrays.

Some examples

Even though I reviewed this, this example section was made with AI, so use this with caution.

Structure of Base-Indexed Addressing

In x86, the effective address is computed as:

1Effective Address = Base Register + (Index Register * Scale) + Displacement

Where:

Example 1: Base + Index Addressing

In this example, we’ll consider a simple array of integers (where each integer is 4 bytes), and we want to load the value at the 3rd index of the array into a register.

1MOV EBX, 2000h      ; Load the base address of the array into EBX
2MOV ESI, 2          ; Load the index (for the 3rd element) into ESI
3MOV EAX, [EBX + ESI * 4] ; Load the 3rd element (EBX + 2 * 4 = 2008h) into EAX

Breakdown:

Example 2: Base + Index + Displacement Addressing

This example introduces a displacement (offset) into the calculation, which is useful for accessing a field inside a structure.

Consider a structure like this:

1struct {
2    int x;
3    int y;
4    int z;
5} Point;

The size of each field is 4 bytes. If we want to access the y value of the 3rd Point in an array of Point structures, we can use base-indexed addressing with displacement:

1MOV EBX, 2000h      ; Load the base address of the array into EBX
2MOV ESI, 2          ; Index for the 3rd Point (index 2)
3MOV EAX, [EBX + ESI * 12 + 4] ; Load the 'y' field of the 3rd Point into EAX

Breakdown:

Example 3: Base + Index without Scale

This example shows a case where no scale factor is used, which can occur when dealing with byte arrays (where each element is 1 byte).

1MOV EBX, 2000h       ; Load the base address of the byte array into EBX
2MOV ESI, 3           ; Load the index for the 4th byte (index 3) into ESI
3MOV AL, [EBX + ESI]  ; Load the 4th byte (EBX + 3) into AL

Breakdown:

References: