【问题标题】:Understanding the Address location denoted by Qword ptr?了解 Qword ptr 表示的地址位置?
【发布时间】:2026-01-20 02:50:02
【问题描述】:

我遇到了以下汇编指令and rax, qword ptr [0xff5ff098]

我想知道的是什么是内存地址,它将在以下指令中访问。 内存地址0xff5ff098是零扩展还是最高位扩展?

Intel Pin 工具中,api IARG_MEMORYREAD_EA 将其扩展为 1,即它提供以下地址 0xffffffffff5ff098 。这个地址是不是可能的地址?

我正在使用 64 位机器。

【问题讨论】:

  • 我很确定在过去的一年中,有一个关于 32 位绝对地址是零还是符号扩展的问题,但这可能不是完全重复的。我似乎记得 Jester 回答过。

标签: assembly x86 x86-64 intel-pin


【解决方案1】:

它是如何编码的? RIP 相对还是绝对?

如果是绝对的,它使用符号扩展-disp32 寻址模式(因为32-bit displacements in addressing modes are always sign extended,即使不涉及寄存器)。

如果它是 RIP 相关的,那么您的反汇编程序应该会向您显示正确的最终地址,由 RIP + rel32 计算得出。

您的反汇编程序或 PIN 显示不正确,因为如果它真的符号扩展为 64 位,您的反汇编程序应该会向您显示。


是的,在 x86-64 中,RIP 相对寻址和绝对寻址都是可能的。

x86-32 有两种冗余方式来编码[disp32] 寻址模式而无需寄存器。 x86-64 将较短的地址重新用作 RIP 相对地址,并将较长的地址保留为 [sign-extended-disp32] 绝对寻址。

我将使用 NASM 语法作为示例。您可以使用 default rel 默认使用 RIP-relative,您可以根据具体情况进行覆盖,如下所示:

  MOV     RAX, [abs FS:_start]    ; _start just as something that assembles
  MOV     RAX, [rel FS:_start]    ; RIP-rel for thread-local is usually not useful!

 64 48 8b 04 25 b5 00 40 00   mov rax,QWORD PTR fs:0x4000b5
 64 48 8b 05 e7 fe ff ff      mov rax,QWORD PTR fs:[rip+0xfffffffffffffee7]  # 4000b5 <_start>

这个地址是可能的地址吗?

是的,使用规范范围上半部分的地址。例如less /proc/self/maps 表明 Linux 将其导出的 vsyscall 页面映射到高地址空间:

ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

规范地址意味着位 [63:48] 是位 47 的副本。即,地址是您通过符号扩展低 48 位获得的地址。非规范地址总是会在当前硬件上出错,所以如果你想用那些冗余位实现标记指针之类的东西,你仍然需要在取消引用之前重做符号扩展。


请注意,qword ptr 告诉您操作数大小,而不是有关寻址模式如何编码的任何信息。

【讨论】: