【问题标题】:converting assembler function in Delphi which runs on windows to delphi/c++ to execute on Linux将在 Windows 上运行的 Delphi 中的汇编程序函数转换为在 Linux 上执行的 delphi/c++
【发布时间】:2026-01-04 02:15:02
【问题描述】:

我的应用程序中有这个汇编器函数,用 delphi 编写,它在 windows 上执行得很好。但是我的要求是在 Linux 上执行它,因为我在 Linux 上迁移我的应用程序。在 Linux 中编译此函数时出现错误:“不支持的语言功能:'ASM'”。

任何人都可以帮助或建议如何在 c++ 或 delphi 中实现它,以便它适用于 Linux。 分享我的代码:

type 
  PVersionizedPointer = ^TVersionizedPointer; 
  TVersionizedPointer = packed record 
    Ver : NativeInt; 
    Ptr : Pointer; 
  end; 
  TVersionizedPointerStorage = array[0 .. 2 * sizeof(TVersionizedPointer) - 1] of byte; 

function GetVersionizedPointer(var PointerStorage : TVersionizedPointerStorage) : 
    PVersionizedPointer; assembler;
const
  vp_size = sizeof(TVersionizedPointer);  
      // Note: sizeof(any) inside asm is always $31
  asm
    {$ifdef CPUX86}
      add EAX, vp_size - 1
      and EAX, not(vp_size - 1)
    {$endif}
    {$ifdef CPUX64}
      mov RAX, RCX
      add RAX, vp_size - 1
      and RAX, not(vp_size - 1)
    {$endif}
  end;
end;

【问题讨论】:

  • 你能给出TVersionizedPointerStorage的定义吗?
  • 对代码应该做什么的一些提示会有所帮助。答案可能是不要打扰汇编代码并相信编译器会生成好的代码
  • 我一定会分享信息的。
  • 请不要在 cmets 中添加详细信息。您可以编辑问题并在此处添加信息
  • 确定@David。下次会注意的。

标签: c++ linux delphi assembly


【解决方案1】:

只关注 x86 版本的功能可能是最简单的:

function GetVersionizedPointer(var PointerStorage: TVersionizedPointerStorage): PVersionizedPointer;
const
  vp_size = sizeof(TVersionizedPointer);
asm
  add EAX, vp_size - 1
  and EAX, not(vp_size - 1)
end;

x86 ABI 表示PointerStorage 的地址被传递给EAX 中的函数。返回值,另一个地址,也在EAX 中重新调整。这些知识让我们了解函数的作用,并允许我们用 Pascal 编写它:

function GetVersionizedPointer(var PointerStorage: TVersionizedPointerStorage): PVersionizedPointer;
var
  Address: NativeUInt;
begin
  Address := NativeUInt(@PointerStorage);
  Address := Address + (SizeOf(TVersionizedPointer) - 1);
  Address := Address and not (SizeOf(TVersionizedPointer) - 1);
  Result := PVersionizedPointer(Address);
end;

我已经把它写得相当冗长,以明确每个步骤在做什么。地址变量被分配了PointerStorage的地址,因此与原始版本中的EAX作用相同。

通过使用这个纯 Pascal 版本并丢失汇编代码,让您未来的生活更轻松。

【讨论】:

  • 备注:这种函数可能受益于内联。并且内联这样的 pascal 代码很可能比调用外部 asm 存根更快。 :)
【解决方案2】:

这个函数的目的是对齐内存中的存储。它是perfectly pointless in modern Intel/AMD CPUs。它可能对 8086 CPU 有好处,但现在没有了。听起来绝对像是错误/过早的优化。

整个对齐子程序可以避免:它会使代码更简洁,也更快。摆脱TVersionizedPointerStorage,只使用TVersionizedPointer

不对齐数据会更快,因为您不再需要计算任何对齐,您只需使用所需的内存,而TVersionizedPointerStorage 总是使用两倍的大小,因此会污染 CPU L1缓存没有任何好处,并添加了不需要的内存分配。

【讨论】:

  • 嗨@Arnaud 实际上这是 90 年代的非常古老的代码,由其他人编写,所以最近这个应用程序/工具来到我们这里,我们正在努力使其在 lInux 上工作并完全理解它。
  • 然后从TVersionizedPointerStorage 等已弃用的技巧中清除它。这肯定有助于理解它。
最近更新 更多