繁体   English   中英

rip 可以与具有 RIP 相对寻址的另一个寄存器一起使用吗?

[英]Can rip be used with another register with RIP-relative addressing?

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

XXX ptr [base + index * size + displacement]

其中 XXX 是某个大小(字节/字/双字/等), baseindex都是寄存器, size是 2 的小幂, displacement是有符号值。

amd64 引入了 rip 相对寻址。 据我了解,我应该能够使用rip作为基址寄存器。 但是,当我使用 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然后抵消它?

不, [RIP + rel32]是唯一涉及 RIP 的寻址模式。 另请参阅引用内存位置的内容。 (x86 寻址模式)

如果您希望索引静态数组的效率最高,则需要编写与位置相关的代码,以便在正常寻址模式下将表地址用作 32 位绝对disp32 这在 Linux 中与位置相关的可执行文件中是允许的,但不允许共享库(必须是 PIC)。 看到x86-64 Linux 中不再允许使用 32 位绝对地址了吗? 当 gcc 默认配置为制作 PIE 时,如何使用-fno-pie -no-pie

否则对于位置无关的数组索引, lea rsi, [rip + Lsomething]并使用指针增量或[rsi + rdi*1 + constant]寻址模式,或任何其他替代方法。 非索引寻址模式有时会在 Intel CPU 上节省一个 uop,因此指针增量可能会很好,特别是如果您正在展开,那么每个指针的add可以超过其自身的成本,而不是对多个数组使用相同的索引。 )


它不是任意寻址模式下的“RIP 作为基址寄存器”; 机器代码编码中没有空间 x86-64 有 16 个可能的基址寄存器,使用 ModR/M 或 SIB 字节中的 3 位 + 可选 REX 前缀中的 1 位进行编码。 使 RIP 可用作具有任意寻址模式的基础将需要删除一些其他寄存器,并在 32 位和 64 位模式之间在有效地址解码方面产生许多差异。

x86-32 有 2 种冗余方式来编码[0x123456] ,即 no-base + disp32: 有或没有 SIB 字节,因为 SIB 有无基址和无索引的编码。 请参阅http://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing以获得漂亮的表格,或参阅英特尔的手册。

无索引 SIB 编码使得编码[esp]而不是[esp+esp]成为可能,因为表示 base=RSP 的 ModR/M 编码是表示“有一个 SIB”的转义码。 他们可以设计的,所以你可以使用esp作为比其他基地的指数esp ,但没有人愿意使用esp作为摆在首位的索引。 有趣的事实:无碱基(带有disp32 )编码使用没有位移的[ebp] ,这就是为什么[ebp]实际上被编码为[ebp + disp8=0] 在 x86-64 模式下,这也适用于 R13。

x86-64 将[disp32]的较短(无 SIB)编码重新用于[RIP + disp32] ,也称为[RIP + rel32]

32 位绝对地址 ( [disp32] ) 仍然可以使用更长的 SIB 编码进行编码 (这是 NASM 默认情况下所做的,如果您不使用default rel 。)甚至没有[RIP + disp8] (例如用于加载附近的代码地址)。 ModR/M 字节的 Mod 和 M 字段中恰好有一个位模式,用于编码 RIP 相对地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM