当我使用拆卸该指令pad
对Radare我得到一个LEA
与rip
[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [rip + 0x80490c8]
我从这篇文章中得到了这条指令here我很困惑为什么反汇编显示rip + 0x80490c8
,当原始帖子声称它相当于mov
? 这是正确的反汇编输出吗?为什么指令指针会在LEA
? 这是一个隐含的基础,还是原始海报弄错了?
当我使用拆卸该指令pad
对Radare我得到一个LEA
与rip
[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [rip + 0x80490c8]
我从这篇文章中得到了这条指令here我很困惑为什么反汇编显示rip + 0x80490c8
,当原始帖子声称它相当于mov
? 这是正确的反汇编输出吗?为什么指令指针会在LEA
? 这是一个隐含的基础,还是原始海报弄错了?
这只是位的问题。在所示示例中,十六进制对是使用 64 位程序集反汇编的,您可能希望将其更改为 32 位程序集。只需告诉radare您正在使用32位,它就会为您完成工作:
[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [rip + 0x80490c8]
[0x00000000]> e asm.bits =32
[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [0x80490c8]
与被视为绝对地址(使用 32 位立即偏移寻址)的 32 位模式指令不同,64 位模式(又名长模式)通常使用从当前 RIP 开始的 32 位偏移,而不是像以前那样从 0x00000000 开始。这意味着你不必知道你想要引用的东西的绝对地址,你只需要知道它离当前正在执行的指令有多远。
很少有寻址模式使用完整的 64 位绝对地址。大多数寻址模式是相对于 64 位寄存器之一(通常是 RIP)的 32 位偏移。
32 位 x86 有 2 种冗余编码方式[disp32]
(没有寄存器):有和没有 SIB 字节。汇编程序当然会始终使用较短的形式,这就是您问题中的链接所显示的内容。
您正在反汇编为 64 位机器代码。
x86-64 将没有-SIB 的版本重新用于表示[RIP + rel32]
,让更长的有[sign_extended_disp32]
-SIB版本仍然意味着当您使用带有 GP 寄存器的 disp32 时。(RIP-relative 不能与任何 GP 寄存器结合使用;只有这一种特定的 ModR/M 编码。)
在 NASM 语法中,[rel foo]
vs [abs foo]
. 或使用default rel
.
AFAIK,lea r32, [disp32]
而不是对mov r32, imm32
我所知道的任何 CPU 上的性能都没有用,除了故意使指令更长而不是用 NOP 填充。
lea
静态地址的唯一用例是使用 RIP 相对 LEA 的 64 位代码。
有关 LEA 的更多信息,请参阅此规范答案,但实际上这个问题与 LEA 无关,并且会发生在任何使用以disp32
错误模式解码的ModR/M 寻址模式的指令中。 您之所以遇到此问题,是因为您发现了一个示例,该示例将在 32 位模式下使用低效lea
与高效mov
-immediate 进行比较。