Article by Ayman Alheraki on January 11 2026 10:37 AM
The Scale-Index-Base (SIB) byte is an essential extension of the ModR/M byte in x86-64 instruction encoding, enabling complex memory addressing modes beyond simple base register addressing. The SIB byte allows combinations of scaled index registers and base registers, providing powerful addressing flexibility needed for high-performance and complex software implementations.
The SIB byte follows the ModR/M byte when the R/M field of the ModR/M byte is set to 100 (binary), indicating that a SIB byte is required to fully specify the effective address. It provides three components:
Scale factor to multiply the index register
Index register to provide scaled offset
Base register to provide the starting point of the memory address
Together, these fields allow addressing of memory using the formula:
Effective Address = Base + (Index × Scale) + Displacement
This is critical for supporting array indexing, pointer arithmetic, and complex data structures.
The SIB byte is 8 bits, divided as follows:
| Bits | Name | Description |
|---|---|---|
| 7-6 | Scale | Scale factor (00=1, 01=2, 10=4, 11=8) |
| 5-3 | Index | Index register (3 bits) |
| 2-0 | Base | Base register (3 bits) |
Scale (2 bits): Specifies the multiplier for the index register. Valid values are 1, 2, 4, or 8.
Index (3 bits): Specifies the index register. If set to 100 (binary), it means no index is used.
Base (3 bits): Specifies the base register for the addressing mode.
| Scale Bits | Scale Factor | Usage |
|---|---|---|
| 00 | 1 | No scaling (index multiplied by 1) |
| 01 | 2 | Index multiplied by 2 |
| 10 | 4 | Index multiplied by 4 |
| 11 | 8 | Index multiplied by 8 |
Scaling is typically used to access elements of arrays or structures, where the index represents an element offset, and scale corresponds to element size in bytes.
The index field specifies which register is used as the index. The register codes correspond to:
| Index Bits | Register | Description |
|---|---|---|
| 000 | RAX | General-purpose register |
| 001 | RCX | General-purpose register |
| 010 | RDX | General-purpose register |
| 011 | RBX | General-purpose register |
| 100 | None | No index (special encoding) |
| 101 | RBP | Base pointer (can be index) |
| 110 | RSI | General-purpose register |
| 111 | RDI | General-purpose register |
When the index field is set to 100 (binary), it signifies that there is no index register used in the addressing, and only the base and displacement (if any) contribute to the address.
The base field specifies the base register used in the memory addressing. The register codes correspond to:
| Base Bits | Register | Description |
|---|---|---|
| 000 | RAX | Base register |
| 001 | RCX | Base register |
| 010 | RDX | Base register |
| 011 | RBX | Base register |
| 100 | RSP | Stack pointer register (special case) |
| 101 | RBP | Base pointer or displacement-only address (depends on Mod field) |
| 110 | RSI | Base register |
| 111 | RDI | Base register |
Special cases occur depending on the Mod field of the ModR/M byte:
When Mod = 00 and Base = 101, this encodes a displacement-only addressing mode (no base register, a 32-bit displacement follows).
The RSP base code is never used directly without a SIB byte, as it conflicts with ModR/M encoding.
The SIB byte enables multiple complex addressing scenarios:
Base + Index × Scale + Displacement: The most common use, allowing calculation of an effective address with a base register, scaled index register, and optional displacement.
Base + Index × Scale: When displacement is zero, the effective address is computed solely from base and scaled index.
Index × Scale + Displacement (No Base): By setting Base field to 101 and Mod field to 00, displacement-only addressing combined with scaled index is possible.
Base Only (No Index): When Index field is 100 (no index), SIB allows addressing with just a base register and optional displacement.
[RAX + RDX*4 + 16]Mod = 10 (32-bit displacement)
Reg = destination/source register (depending on instruction)
R/M = 100 to indicate SIB byte follows
SIB byte components:
Scale = 10 (4)
Index = 010 (RDX)
Base = 000 (RAX)
Displacement = 0x10 (32-bit)
Encoding:
ModR/M: 10 (Mod) + reg + 100 (R/M)
SIB: 10 (scale) + 010 (index) + 000 (base)
Displacement: 4 bytes (0x10)
[RSP + RBP*1]Mod = 00 (no displacement)
R/M = 100 (SIB byte follows)
SIB:
Scale = 00 (1)
Index = 101 (RBP)
Base = 100 (RSP)
This is a valid addressing mode where RSP is the base and RBP is used as an index scaled by 1.
The REX prefix extends the SIB byte’s Index and Base fields by adding a high bit.
REX.X extends the Index field, allowing access to registers R8–R15 as index.
REX.B extends the Base field, allowing access to registers R8–R15 as base.
Example: To encode [R8 + R9*4] the REX prefix must set bits to extend these registers, as their lower 3-bit codes overlap with legacy registers.
The SIB byte is mandatory for addressing modes involving RSP or any scaled indexing.
Use of SIB byte slightly increases instruction length but enables powerful addressing schemes.
Careful attention to the interaction between Mod, R/M, SIB, displacement, and REX prefixes is required to ensure correct encoding.
Not all instructions require or support SIB bytes; it is specific to memory operand addressing.
The SIB byte is an 8-bit extension to ModR/M that provides scale, index, and base for complex memory addressing.
It encodes a scale factor (1, 2, 4, or 8), an index register (or no index), and a base register (or displacement-only).
The SIB byte significantly expands the addressing modes available in x86-64 architecture.
Proper handling of the SIB byte and its interplay with ModR/M and REX prefixes is essential for correct machine code generation in an assembler.