Is it possible to use the 8-bit registers (al, ah, bl, bh, r8b
) in indexed addressing modes in x86-64? For example:
mov ecx, [rsi + bl]
mov edx, [rdx + dh * 2]
In particular, this would let you use the bottom 8-bits of a register as a 0-255 offset, which could be useful for some kernels.
I poured over the Intel manuals and they aren't explicit on the matter, but all the examples they give only have 32-bit or 64-bit base and index registers. In 32-bit code I only saw 16 or 32-bit registers. Looking at the details of mod-r/m and SIB byte encoding also seems to point towards "no" but that's complex enough with enough corner cases that I'm not sure I got it right.
I'm mostly interested in the x86-64 behavior, but of course if it's possible in 32-bit mode only I'd like to know.
As an add-on question too small and related to deserve another post - can 16-bit registers be used for base or index? E.g., mov rax, [rbx + cx]
. My investigation pointed towards basically the same answer as above: probably not.
[reg16 + disp32]
. You need amovzx
. The tables that show the encoding really do enumerate all possible encodings. – Peter Cordesal
, because there are no 8-bit addressing modes. I understand the motivation for the question, though: when I was new to x86, I kept wondering if there were addressing modes I didn't know about. But it turns out there's only[base + idx*scale + disp8/disp32]
, or any subset of that omitting one or two of those three components. (Plus RIP-relative in 64-bit mode). That's why I wrote this answer, which might make a good Docs topic at this point. – Peter Cordes[disp + reg8 + reg32*scale]
addressing mode, which is exactly what I want (in 32-bit mode). It seems like it was a typo though and they meantdisp8 + reg32 ...
instead. – BeeOnRopexlat
(orxlatb
). It does (implicitly) use the 8-bit registeral
as the index into a table implicitly pointed to by[r/e]bx
. Unfortunately it's a horrible waste of encoding space and can only load into theal
register. – EOF