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?