本文介绍了rip是否可以与具有RIP相对寻址的另一个寄存器一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我熟悉这种形式的内存引用:

I'm familiar with memory references of this form:

XXX ptr [base + index * size + displacement]

其中XXX是某种大小(字节/字/双字/等),baseindex都是寄存器,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相对寻址的另一个寄存器一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 08:24