Assembly 为什么';mov&x27;指令导致目标寄存器的高位中存在多余字节?

Assembly 为什么';mov&x27;指令导致目标寄存器的高位中存在多余字节?,assembly,x86-64,Assembly,X86 64,我试图在一个非常简单的for循环中调试崩溃。C++非常类似于: bool test(uint64_t value) { auto iter = std::find_if(..., ..., [value](const auto& element) { return element.proxy ? element.proxy->value == value : false; //element.proxy is a pointer

我试图在一个非常简单的for循环中调试崩溃。C++非常类似于:

   bool test(uint64_t value) {
       auto iter = std::find_if(..., ..., [value](const auto& element) {
           return element.proxy ? element.proxy->value == value : false; //element.proxy is a pointer
       }
       ...
   }
生成的程序集非常简单,基本上是一个展开的for循环

  ...
  6b5b72:   4c 8b 6d 08             mov    r13,QWORD PTR [rbp+0x8]
  6b5b76:   4d 85 ed                test   r13,r13
  6b5b79:   74 06                   je     6b5b81 
  6b5b7b:   41 3b 55 00             cmp    edx,DWORD PTR [r13+0x0]
  6b5b7f:   74 7f                   je     6b5c00 
  6b5b81:   4c 8b 6d 48             mov    r13,QWORD PTR [rbp+0x48]
  6b5b85:   4d 85 ed                test   r13,r13
  6b5b88:   74 0a                   je     6b5b94 
  6b5b8a:   41 3b 55 00             cmp    edx,DWORD PTR [r13+0x0]
  6b5b8e:   0f 84 bc 01 00 00       je     6b5d50 
  6b5b94:   4c 8b ad 88 00 00 00    mov    r13,QWORD PTR [rbp+0x88]
  6b5b9b:   4d 85 ed                test   r13,r13
  6b5b9e:   74 0a                   je     6b5e10
  6b5ba0:   41 3b 55 00             cmp    edx,DWORD PTR [r13+0x0]   ;We will crash here
  6b5ba4:   0f 84 66 02 00 00       je     6b5e10 
  6b5baa:   4c 8b ad c8 00 00 00    mov    r13,QWORD PTR [rbp+0xc8]
  6b5bb1:   4d 85 ed                test   r13,r13
  6b5bb4:   74 0a                   je     6b5bc0 
  6b5bb6:   41 3b 55 00             cmp    edx,DWORD PTR [r13+0x0]
  6b5bba:   0f 84 80 01 00 00       je     6b5d40 
  6b5bc0:   48 81 c5 00 01 00 00    add    rbp,0x100
  6b5bc7:   48 39 c5                cmp    rbp,rax
  ...
  (note: there might be slight transcription errors in the raw hex and je addresses which I am attempting to fix)
程序在第6b5ba0行崩溃。$r13的值远远超出了我预期的有效内存地址

(gdb) p/x $r13
$130 = 0x40007f7bd5b3fde8
但问题是,基于我期望$r13等于$rbp+0x88所指向的64位值的程序集。如果我们在gdb中查看该值,我们会得到:

(gdb) p *(uint64_t **)($rbp+0x88)
$132 = (uint64_t *) 0x7f7bd5b3fde8
这是$r13中的值,除非地址前面有0x4000。我还验证了0x7f7bd5b3fde8处的数据是否符合我的预期。看看输出,我不知道这是怎么可能的,特别是因为我必须假设前面对应于展开循环的指令没有触发这一点


这些额外的字节是如何到达那里的?

您能发布足够的代码使您的示例可以重现吗?这是否能持续重现?您是否在6b5b94上中断,确保
[rbp+0x88]
符合您的预期,然后单步验证
r13
是否错误?您确定这是正确的反汇编吗。我认为
74 0a
0f 84 66 02 00 00
具有相同的分支目标
6b5e10
是毫无意义的,因为它们之间只有一条其他指令。您的反汇编肯定是错误的<代码>74 0aat
6b5b9e
je 6b5baa
,而不是
je 6b5e10
。假设您没有手工编辑显示的内容,则会出现严重错误。事实上,
0x40007f7bd5b3fde8
是非规范的(不是48或57位符号扩展),因此取消引用它肯定会出错。你的CPU是否超时了?或者你的RAM会出故障吗?这也许可以解释“加载”一个不在内存中的值。