将在 Windows 上运行的 Delphi 中的汇编程序函数转换为 Delphi/c++ 以在 Linux 上执行

Ann*_*nna 3 c++ linux delphi assembly

我在用 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;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 5

专注于 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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

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

使用这个纯粹的 Pascal 版本,让你的生活在未来更轻松,而不会丢失汇编代码。