Opt.out是什么意思?

时间:2015-06-24 09:54:12

标签: delphi debugging callstack delphi-xe7

看着调用堆栈我刚才注意到了这一点:

enter image description here

请注意顶部的Opt.out

好奇, Opt.out意味着什么?

以下是我要介绍的片段:

function BinaryEquals(Left, Right: pointer; Size: integer): boolean;
....
{$IFDEF CPUX64}
asm
 ....
  sub r8,4
@loop1:
  inc  R8

1 个答案:

答案 0 :(得分:7)

我不确定助记符的含义,但调用堆栈告诉你的是它无法可靠地报告参数的值。

考虑这个程序:

procedure Foo(Bar: Pointer);
asm
  xor eax,eax
end;

begin
  Foo(nil);
end.

进入Foo。执行此操作时,调用堆栈在32位中显示如下:

Project1.Foo(nil)
Project1.Project1
:76f5337a kernel32.BaseThreadInitThunk + 0x12
:775b92e2 ntdll.RtlInitializeExceptionChain + 0x63
:775b92b5 ntdll.RtlInitializeExceptionChain + 0x36

这是64位:

Project1.Foo(nil)
Project1.Project1
:00000000772959CD ; C:\Windows\system32\kernel32.dll
:00000000773CB981 ; ntdll.dll

然后跨过Foo的第一行。现在调用堆栈在32位中看起来像这样:

Project1.Foo(???)
Project1.Project1
:76f5337a kernel32.BaseThreadInitThunk + 0x12
:775b92e2 ntdll.RtlInitializeExceptionChain + 0x63
:775b92b5 ntdll.RtlInitializeExceptionChain + 0x36

这是64位:

Project1.Foo(Opt.out)
Project1.Project1
:00000000772959CD ; C:\Windows\system32\kernel32.dll
:00000000773CB981 ; ntdll.dll

调试器告诉你的是参数到达寄存器。一旦执行了asm函数的主体,它就无法控制对寄存器的操作。因此它拒绝尝试报告参数值。

如果切换到32位编译器,并更改调用约定以使参数到达堆栈而不是寄存器,则行为会有所不同。在这种情况下,调试器会自信地报告参数值,因为它认为您不会丢弃堆栈。

使用???明确了32位。文本Opt.out用于64位的原因我不知道,但其含义很明显。