问题描述
我熟悉这种形式的内存引用:
I'm familiar with memory references of this form:
XXX ptr [base + index * size + displacement]
其中XXX是某种大小(字节/字/双字/等),base
和index
都是寄存器,size
是2的小数幂,并且displacement
是有符号值.
where XXX is some size (byte/word/dword/etc), both base
and index
are registers, size
is a small power of two, and displacement
is a signed value.
amd64引入了rip-relative寻址.据我了解,我应该能够将rip
用作基址寄存器.但是,当我尝试使用clang-900.0.39.2时:
amd64 introduced rip-relative addressing. As I understand it, I should be able to use rip
as a base register. However, when I try this with clang-900.0.39.2:
mov r8b, byte ptr [rip + rdi * 1 + Lsomething]
我得到:
mov r8b, byte ptr [rip + rdi * 1 + Lsomething]
当使用rip
作为基址寄存器时,是否不可能使用索引寄存器?我必须使用lea
来计算rip + Lsomething
,然后偏移到其中吗?
Is it impossible to use an index register when using rip
as the base register? Do I have to use lea
to compute rip + Lsomething
and then offset into that?
推荐答案
否,[RIP + rel32]
是涉及RIP的唯一寻址模式.另请参见.
No, [RIP + rel32]
is the only addressing mode involving RIP. See also Referencing the contents of a memory location. (x86 addressing modes).
如果要最大效率地索引静态数组,则需要制作与位置有关的代码,以便可以在正常寻址模式下将表地址用作32位绝对值disp32
.在Linux中,位置相关的可执行文件允许这样做,但共享库(必须是PIC)不允许这样做.请参阅 32位绝对地址x86-64 Linux?了解如何在默认情况下将gcc配置为创建PIE时使用-fno-pie -no-pie
.
If you want maximum efficiency for indexing a static array, you need to make position-dependent code so you can use the table address as a 32-bit absolute disp32
in a normal addressing mode. This is allowed in Linux in position-depended executables, but not shared libraries (which have to be PIC). See 32-bit absolute addresses no longer allowed in x86-64 Linux? for how to use -fno-pie -no-pie
when gcc is configured by default to make PIEs.
在任意寻址模式下,它不是将RIP作为基址寄存器";机器代码编码中没有空间. x86-64有16个可能的基址寄存器,用ModR/M或SIB字节中的3位+可选REX前缀中的1位编码.要使RIP可用作任意寻址模式的基础,就需要增加一些其他寄存器,并在32位和64位模式之间的有效地址解码方面造成很大差异.
It's not "RIP as a base register" in arbitrary addressing modes; there isn't room in the machine-code encoding for that. x86-64 has 16 possible base registers, encoded with 3 bits in the ModR/M or SIB byte + 1 bit in the optional REX prefix. Making RIP usable as a base with arbitrary addressing modes would have required bumping out some other register, and creating a lot of differences in effective-address decoding between 32 and 64-bit mode.
x86-32有2种冗余的编码[0x123456]
的方法,即无基+ disp32:有或没有SIB字节,因为SIB具有无基和无索引的编码.请参见 http://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing 以获得一张漂亮的桌子,或参阅Intel的手册.
x86-32 has 2 redundant ways to encode [0x123456]
, i.e. no-base + disp32: with or without a SIB byte, because SIB has an encoding for no-base and no-index. See http://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing for a nice table, or see Intel's manuals.
无索引的SIB编码使对[esp]
而不是[esp+esp]
进行编码成为可能,因为表示base = RSP的ModR/M编码是表示有一个SIB"的转义码.他们本可以设计它,所以您可以将esp
用作除esp
以外的碱基的索引,但是没有人首先希望将esp
用作索引.有趣的事实:无基(带有disp32
)编码使用的是没有位移的[ebp]
,这就是为什么[ebp]
实际上被编码为[ebp + disp8=0]
的原因.在x86-64模式下,这也适用于R13.
The no-index SIB encoding makes it possible to encode [esp]
instead of [esp+esp]
, because the ModR/M encoding that would mean base=RSP is the escape code that means "there's a SIB". They could have designed it so you could use esp
as an index for bases other than esp
, but nobody wants to use esp
as an index in the first place. Fun fact: the no-base (with disp32
) encoding uses what would have been the [ebp]
with no displacement, which is why [ebp]
is actually encoded as [ebp + disp8=0]
. In x86-64 mode, this applies to R13 as well.
x86-64将[disp32]
的较短(无SIB)编码重新用于[RIP + disp32]
,又名[RIP + rel32]
.
x86-64 re-purposes the shorter (no SIB) encoding for [disp32]
into [RIP + disp32]
, aka [RIP + rel32]
.
32位绝对地址([disp32]
)仍可以使用较长的SIB编码进行编码. (如果您不使用default rel
,这是NASM的默认设置.)甚至没有[RIP + disp8]
(例如,用于加载附近的代码地址).在ModR/M字节的Mod和M字段中,只有一个位模式可以对RIP相对地址进行编码.
32-bit absolute addresses ([disp32]
) are still encodeable with the longer SIB encoding. (This is what NASM does by default, if you don't use default rel
.) There's not even a [RIP + disp8]
(e.g. for loading nearby code addresses). There is exactly one bit-pattern in the Mod and M fields of the ModR/M byte that encodes a RIP-relative address.
这篇关于rip是否可以与具有RIP相对寻址的另一个寄存器一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!