64 位 Delphi 11 Windows 上的内联汇编器

0 delphi assembly inline-assembly

我正在将 Windows XP 上的 Delphi 6 项目转换为 Windows 11 上的 Delphi 11。我有一个很可能很常见的问题,但不知道 Assembly 我有点困惑。

//This complies fine in 64 or 32 bit
{$IFDEF WIN32}
asm
    mov edx, aStream
    mov eax, aObject
    call aPointer
end;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
//this does not compile in 64 due to inline Assembly
{$IFDEF WIN64}
asm
    mov ecx, aStream
    mov eax, aObject
    call aPointer
end;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)

有没有好的参考资料可以帮助我快速学习?有一个简单的解决方案吗?

Arn*_*hez 6

所以最好的asm就是不asm写。

我们可以更换

{$IFDEF WIN32}
asm
    mov edx, aStream
    mov eax, aObject
    call aPointer
end;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)

与本机帕斯卡代码。

这是一个无操作,只是一个函数调用。

只需将其替换为

type
  TMethodCallWithStream = procedure(Instance: TObject; Str: TStream);
...
   TMethodCallWithStream(aPointer)(aObject, aStream);
Run Code Online (Sandbox Code Playgroud)

它不会比以前的 asm 代码慢,并且可以在所有平台上运行,包括 Win32 和 WIN64。

这里self作为第一个参数传递。所以实际调用的方法类似于MethodName(Stream: TStream);但这就是方法的调用方式:self作为第一个参数传递 -eax在 Win32 程序集中。那么第二个参数实际上是源代码中的第一个方法参数 -edx在 Win32 程序集中。您可以使用TMethod包装器,但会更复杂。

有关如何调用方法的参考,请参阅Delphi 文档:

根据寄存器约定,Self 的行为就好像它是在所有其他参数之前声明的一样。因此它总是在 EAX 寄存器中传递。

编辑/提示:当您对新目标进行一些重构时,重写越少越好。您应该使用工作目标(此处为 Win32)作为参考,并始终验证您在其代码中所做的任何修改。所以在这里,用 pascal 代码替换 asm 确实有意义。不要再重写了。然后,当所有内容都在 Win32 和 Win64 上编译时,确保它仍然可以在 Win32 上运行,然后看看它在 Win64 上是否正常。使用调试器来验证每个修改。我对重构的建议是首先让它运行起来,永远不要破坏现有的,然后让它变得更好——如果你有时间的话。