Dess Asked: 2024-10-23 23:47:09 +0800 CST2024-10-23 23:47:09 +0800 CST 2024-10-23 23:47:09 +0800 CST 寻址模式 [IndexReg * ScaleFactor + Offset] 用于什么? 772 在X86汇编中,什么类型的操作使用这种格式的寻址模式? IndexReg * ScaleFactor + Offset mov rax, [r15 * 8 + 56] assembly 1 个回答 Voted Best Answer Peter Cordes 2024-10-24T00:31:27+08:002024-10-24T00:31:27+08:00 通常,作为disp32数组的绝对地址,就像mov eax, [arr + rdi*4],而不是像你的这样的小整数常数56。 这在 16 位和 32 位模式下始终是可能的,但在 64 位模式下仅适用于非 PIE 代码模型,其中静态数据位于虚拟地址空间的底部或顶部 2GiB。(请参阅x86-64 Linux 中不再允许使用 32 位绝对地址? / Mach-O 64 位格式不支持 32 位绝对地址。NASM 访问数组) 其他用例包括LEA 进行移位和加法lea eax, [rdi*8 + 56]。 理论上,您可以使用它来遍历一个对齐的数组,其中缩放寄存器保存地址/8,也许在循环中也使用该值作为字节偏移量进入较小元素的数组,例如[rbx + rdi]。 请注意,它只能用 4 字节disp32而不是 1 字节进行编码disp8(https://wiki.osdev.org/X86-64_Instruction_Encoding#SIB),因此机器代码格式不鼓励像您这样的使用[r15*8 + 56]。x86 寻址模式始终有一个基址寄存器和/或一个 disp32,它可以(在 64 位模式之前)保存数组起始的绝对地址。 请参阅引用内存位置的内容。(x86 寻址模式)了解每种 x86 寻址模式的示例用例。(尽管它并不试图详尽地涵盖使用每种寻址模式的所有方法。)
通常,作为
disp32
数组的绝对地址,就像mov eax, [arr + rdi*4]
,而不是像你的这样的小整数常数56
。这在 16 位和 32 位模式下始终是可能的,但在 64 位模式下仅适用于非 PIE 代码模型,其中静态数据位于虚拟地址空间的底部或顶部 2GiB。(请参阅x86-64 Linux 中不再允许使用 32 位绝对地址? / Mach-O 64 位格式不支持 32 位绝对地址。NASM 访问数组)
其他用例包括LEA 进行移位和加法
lea eax, [rdi*8 + 56]
。理论上,您可以使用它来遍历一个对齐的数组,其中缩放寄存器保存地址/8,也许在循环中也使用该值作为字节偏移量进入较小元素的数组,例如
[rbx + rdi]
。请注意,它只能用 4 字节
disp32
而不是 1 字节进行编码disp8
(https://wiki.osdev.org/X86-64_Instruction_Encoding#SIB),因此机器代码格式不鼓励像您这样的使用[r15*8 + 56]
。x86 寻址模式始终有一个基址寄存器和/或一个 disp32,它可以(在 64 位模式之前)保存数组起始的绝对地址。请参阅引用内存位置的内容。(x86 寻址模式)了解每种 x86 寻址模式的示例用例。(尽管它并不试图详尽地涵盖使用每种寻址模式的所有方法。)