Delphi DUnit2';被调用的RADDR函数,如何将其转换为64位?

Delphi DUnit2';被调用的RADDR函数,如何将其转换为64位?,delphi,assembly,32bit-64bit,Delphi,Assembly,32bit 64bit,我试图让DUnit2在64位下工作,但我对这种方法的作用感到困惑,更不用说如何将其转换为64位了。纯Pascal会更好,但因为它引用堆栈(ebp),所以可能不可能 function CallerAddr: Pointer; assembler; const CallerIP = $4; asm mov eax, ebp call IsBadPointer test eax,eax jne @@Error mov eax, [ebp].Calle

我试图让DUnit2在64位下工作,但我对这种方法的作用感到困惑,更不用说如何将其转换为64位了。纯Pascal会更好,但因为它引用堆栈(ebp),所以可能不可能

function CallerAddr: Pointer; assembler;
const
  CallerIP = $4;
asm
   mov   eax, ebp
   call  IsBadPointer
   test  eax,eax
   jne   @@Error

   mov   eax, [ebp].CallerIP
   sub   eax, 5   // 5 bytes for call

   push  eax
   call  IsBadPointer
   test  eax,eax
   pop   eax
   je    @@Finish

@@Error:
   xor eax, eax
@@Finish:
end;

谢谢你的快速回复,但它不起作用。当函数退出时,我得到以下访问冲突。异常类别$C0000005,消息为“C0000005访问\u冲突”。−1.完全没有抓住要点。这是原始代码的文字转换-它使用64位寄存器而不是32位寄存器-因此我不能严格地称之为错误答案。然而,这显然是一个毫无帮助的答案,因为它没有显示出理解原始代码的目的或确保此函数实现与原始代码相同的目标的努力。给那些不熟悉Delphi运行时的人一点解释:上面是“常用”的32位x86汇编程序代码使用帧指针的情况;由于功能尾声
推EBP;mov ESP,EBP
结果是
[EBP+4]
始终是返回地址(由用于输入函数的
调用写入)。帧指针在64位上是可选的,通常经过优化,因此简单地用
[RBP+8]
替换
[EBP+4]
是不合适的。Delphi运行时将
RtlCaptureStackBacktrace()
(就像Linux glibc将
backtrace()
)作为此问题的“抽象”解决方案。@frankh在x86上不是可选的帧指针吗?此外,这与Delphi运行时无关。RtlCaptureStackBacktrace是一个Windows API。@David Hefferman:如果帧指针被优化掉,原始海报显示的代码在32位上不能/不会工作。因此,我的假设是(因为它应该适用于Delphi编译代码),它们不是可选的(在32位Delphi中)。
rtlcapturestacktrace()
上的确认-缺少下面的
kernel32.dll
。我之所以发表这篇评论,主要是因为被接受的答案是一个“神奇”的答案,任何不熟悉这一点的人都无法从中学习…@Frank,没有必要做出任何假设。文档清楚地表明,堆栈帧是可选的。
function CallerAddr: Pointer; assembler;
    const
      CallerIP = $4;
    asm
       mov   rax, rcx ;For int.. XMM0 for float
       call  IsBadPointer
       test  rax,rax
       jne   @@Error

       mov   rax, [rcx].CallerIP
       sub   rax, 5   // 5 bytes for call

       push  rax
       call  IsBadPointer
       test  rax,rax
       pop   rax
       je    @@Finish

    @@Error:
       xor rax, rax
    @@Finish:
    end;
function RtlCaptureStackBackTrace(FramesToSkip: ULONG; FramesToCapture: ULONG; 
  out BackTrace: Pointer; BackTraceHash: PULONG): USHORT; stdcall; 
  external 'kernel32.dll' name 'RtlCaptureStackBackTrace' delayed;

function CallerAddr: Pointer;
begin
  // Skip 2 Frames, one for the return of CallerAddr and one for the
  // return of RtlCaptureStackBackTrace
  if RtlCaptureStackBackTrace(2, 1, Result, nil) > 0 then
  begin
    if not IsBadPointer(Result) then
      Result := Pointer(NativeInt(Result) - 5)
    else
      Result := nil;
  end
  else
  begin
    Result := nil;
  end;
end;