在 x86-64 索引寻址模式中使用 8 位寄存器 [英] Using 8-bit registers in x86-64 indexed addressing modes

查看:49
本文介绍了在 x86-64 索引寻址模式中使用 8 位寄存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在 x86-64 的索引寻址模式中使用 8 位寄存器(al, ah, bl, bh, r8b)?例如:

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]

特别是,这将允许您使用寄存器的底部 8 位作为 0-255 偏移量,这对某些内核很有用.

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.

我翻遍了英特尔手册,他们没有明确说明这个问题,但他们给出的所有示例都只有 32 位或 64 位基址和索引寄存器.在 32 位代码中,我只看到 16 位或 32 位寄存器.查看 mod-r/m 和 SIB 字节编码的细节似乎也指向否",但这已经足够复杂,有足够多的极端情况,我不确定我是否正确.

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.

我最感兴趣的是 x86-64 的行为,但当然,如果只有在 32 位模式下才有可能,我想知道.

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.

作为一个附加问题太小了,不值得再发表一篇文章 - 16 位寄存器可以用于基址或索引吗?例如,mov rax, [rbx + cx].我的调查指向与上述基本相同的答案:可能不是.

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.

推荐答案

不可以,64 位模式下不能使用 8 位或 16 位寄存器进行寻址计算,32 位模式下也不能使用 8 位寄存器位模式.您可以在 32 位模式下使用 16 位寄存器,在 64 位模式下使用 32 位寄存器,通过使用 0x67 地址大小前缀 字节.

No, you cannot use 8-bit or 16-bit registers in addressing calculations in 64-bit mode, nor can you use 8-bit registers in 32-bit mode. You can use 16-bit registers in 32-bit mode, and 32-bit registers in 64-bit mode, via use of the 0x67 address size prefix byte.

(但使用更窄的寄存器会使整个地址变窄,而不是相对于 32 位数组地址的 16 位索引.任何寄存器都需要与地址相同的宽度,您通常希望与模式匹配除非您在地址空间的低 16 位或低 32 位中有内容.)

(But using a narrower register makes the whole address narrow, not a 16-bit index relative to a 32-bit array address. Any registers need to be the same width as the address, which you normally want to match the mode you're in, unless you have stuff in the low 16 or low 32 bits of address space.)

此表很好地总结了操作数和地址的各种选项尺寸.一般模式是默认地址大小与当前模式相同(即32位模式下32位,64位模式下64位)1,然后如果包含0x67前缀,地址大小改为通常大小的一半(即32位模式下16位,64位模式下32位).

This table summarizes well the various options for operand and address sizes. The general pattern is that the default address size is the same as the current mode (i.e., 32-bits in 32-bit mode, 64-bits in 64-bit mode)1, and then if the 0x67 prefix is included, the address size is changed to half the usual size (i.e., 16-bits in 32-bit mode, 32-bits in 64-bit mode).

这是上面链接的完整表的摘录,仅显示了 64 位长模式行为,对于 REX.W0x66 操作数和 的各种值>0x67 地址大小前缀:

Here's an excerpt of the full table linked above showing 64-bit long-mode behavior only, for various values of the REX.W, 0x66 operand and 0x67 address size prefixes:

<头>
REX.W0x66 前缀(操作数)0x67 前缀(地址)操作数大小(脚注 2)地址大小
0没有没有32 位64 位
0没有32 位32 位
0没有16 位64 位
016 位32 位
1忽略没有64 位64 位
1忽略64 位32 位


1 这似乎很明显,但它与操作数大小在 64 位模式下工作的方式相反:大多数默认为 32 位,即使在 64-位模式,并且需要一个 REX 前缀来将它们提升到 64 位.


1 That might seem obvious, but it's the opposite to the way operand sizes work in 64-bit mode: most default to 32-bits, even in 64-bit mode, and a REX prefix is needed to promote them to 64-bits.

2 一些指令默认为 64 位没有任何 REX 前缀的操作数大小,特别是 pushpopcall 和条件跳转,正如 Peter 指出的下面,这会导致奇怪的情况,其中至少有一些指令(包括 pushpop)不能被编码为使用 32 位操作数,但可以使用16 位操作数(带有 0x66 前缀).

2 Some instructions default to 64-bit operand size without any REX prefix, notably push, pop, call and conditional jumps, and as Peter points out below, this leads to the odd situation where at least some of these instructions (push and pop included) can't be encoded to use 32-bit operands, but can use 16-bit operands (with the 0x66 prefix).

这篇关于在 x86-64 索引寻址模式中使用 8 位寄存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆