Understanding the SIB byte in x86 Assembly

Viewed 1608

I have read every article google has shown about the SIB byte, as well as this video and the Intel Manuals, but still a bit unclear. This page is particularly helpful, with this content:

[ reg32 + eax*n ] MOD = 00
[ reg32 + ebx*n ] 
[ reg32 + ecx*n ]
[ reg32 + edx*n ]
[ reg32 + ebp*n ]
[ reg32 + esi*n ]
[ reg32 + edi*n ]

[ disp + reg8 + eax*n ] MOD = 01
[ disp + reg8 + ebx*n ]
[ disp + reg8 + ecx*n ]
[ disp + reg8 + edx*n ]
[ disp + reg8 + ebp*n ]
[ disp + reg8 + esi*n ]
[ disp + reg8 + edi*n ]

[ disp + reg32 + eax*n ] MOD = 10
[ disp + reg32 + ebx*n ]
[ disp + reg32 + ecx*n ]
[ disp + reg32 + edx*n ]
[ disp + reg32 + ebp*n ]
[ disp + reg32 + esi*n ]
[ disp + reg32 + edi*n ]

[ disp + eax*n ] MOD = 00, and
[ disp + ebx*n ] BASE field = 101
[ disp + ecx*n ]
[ disp + edx*n ]
[ disp + ebp*n ]
[ disp + esi*n ]
[ disp + edi*n ]

where n = 1, 2, 4 or 8.

From my understanding (though none of the docs seem to show this explicitly), the reg is the "base", the eax etc. are the index, and the n is the "scale" factor, as if you were doing this in an array in JavaScript:

base[index * scale]

The scale essentially allows you to jump by a multiple, so if your memory is byte-based, but your object is 32-bits, then you can jump by every 4 bytes using scale factor of 4. That type of thing.

Am I on the right track? I can't tell fully yet.

What I'm confused about is the displacement. How does the displacement play into the equation here? If you were to draw it as a JavaScript array... And in the case of the last batch of examples, like [ disp + eax*n ], there is no reg (what I'm considering the "base"). Does this mean the base is 0? Also, can the disp be another register, or can it only be a static hardcoded value? Finally, what are all the registers that can be used as the base and the index?

Also, what does it mean disp + reg8 + eax*n? Are we literally doing addition here?

0 Answers
Related