当我在Radare上使用pad反汇编此指令时,得到带有LEArip
,当原始帖子声称它等于rip + 0x80490c8吗?这是正确的反汇编输出吗?为什么指令指针位于mov中?那是一个隐含的基础,还是原始的海报犯了错误?

#1 楼

这只是位问题。在所示的示例中,使用64位程序集反汇编了十六进制对,您可能希望将其更改为32位程序集。只需告诉rae您正在使用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位操作码如何与RIP操作数转换为相同的64位操作码(免费)。

–埃文·卡洛尔(Evan Carroll)
18年4月16日在5:03



添加了解释的原因。同样,只需从32位转换为64位

–巨型甜菜
18年4月16日在5:21

@EvanCarroll-如果您已经花了很长时间来熟悉它,这类似于从16位代码变为32位将所有“ ax”(等)引用更改为“ eax”的方式:每种模式都有一些默认设置,这些默认设置旨在使该模式变得明智,这会导致每条指令的解释稍有变化。

–法律
18年4月16日在8:09

@EvanCarroll:32位x86具有2种冗余编码[disp32](无寄存器)的方式:有和没有SIB。 x86-64重新定义了无SIB版本的意思是[RIP + rel32],而较长的有SIB版本的意思仍然是[sign_extended_disp32],就像将disp32与GP寄存器一起使用时一样。在NASM语法中,[rel foo]与[abs foo]相对,或使用默认rel。

– Peter Cordes
18年4月17日在4:57

@Megabeets:仅特殊的mov / ax / eax / rax,mov的moffs形式(以及存储形式)使用完整的64位/ 8字节绝对地址。没有ModR / M寻址模式可与其他接受绝对绝对Disp32的指令一起使用。因此,您的最后一句话可以说没有任何正常的寻址模式。其实那有点奇怪。通常,您只需使用相对于寄存器中地址的较小偏移量,例如[rdi + 8]或相对RIP。但是,是的,在位置相关的代码中,您可以使用[array + rdi]为静态数组建立索引。

– Peter Cordes
18年4月17日在5:04

#2 楼

32位x86有2种冗余方式来编码[disp32](无寄存器):有和没有SIB字节。汇编程序当然总是使用较短的形式,这就是您问题中所显示的链接。

您正在将其汇编为64位机器代码。

x86- 64将不带SIB的版本重新指定为[RIP + rel32],而较长的带SIB的版本仍然表示[sign_extended_disp32],就像将disp32与GP寄存器一起使用时一样。 (RIP相对项无法与任何GP寄存器结合使用;只能使用一种特定的ModR / M编码。) />
AFAIK,[rel foo]而不是[abs foo]对于我所知道的任何CPU的性能都从不有用,除了故意增加一条指令而不是用NOP填充。 default rel静态地址的用例是带有RIP相对LEA的64位代码。使用以错误模式解码的lea r32, [disp32] ModR / M寻址模式的任何指令都会发生这种情况。您之所以遇到这种情况,是因为您找到了一个示例,该示例将低效率的mov r32, imm32与高效的lea-在32位模式下立即进行比较。