简体   繁体   English

将在 windows 上运行的 Delphi 中的汇编程序 function 转换为 delphi/c++ 以在 ZEDC8310A5A3D57473E 上执行

[英]converting assembler function in Delphi which runs on windows to delphi/c++ to execute on Linux

I have this assembler function in my application wriiten in delphi and this executes well on windows.But my requirement is to execute it on Linux as i am migrating my application on Linux. I have this assembler function in my application wriiten in delphi and this executes well on windows.But my requirement is to execute it on Linux as i am migrating my application on Linux. And while compiling this function in Linux i got error: "Unsupported language feature: 'ASM'".在 Linux 中编译此 function 时出现错误:“不支持的语言功能:'ASM'”。

Anybody can help or suggest how to implement it either in c++ or in delphi so that it works for Linux.任何人都可以帮助或建议如何在 c++ 或 delphi 中实现它,以便它适用于 Linux。 sharing my code:分享我的代码:

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;

It's probably easiest just to concentrate on what the x86 version does:只关注 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;

The x86 ABI means that the address of PointerStorage is passed into the function in EAX . x86 ABI 表示PointerStorage的地址传入EAX中的 function 。 The return value, another address, is also retuned in EAX .返回值,另一个地址,也在EAX中重新调整。 That knowledge lets us understand what the function does, and allows us to write it like this in Pascal:这些知识让我们了解 function 做了什么,并允许我们用 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;

I've written it out rather verbosely to make it clear what each step is doing.我已经把它写得相当冗长,以明确每个步骤在做什么。 The address variable is assigned the address of PointerStorage , and so serves the same role as EAX in the original version. address 变量被分配了PointerStorage的地址,因此其作用与原始版本中的EAX相同。

Make your life easier in the future by using this pure Pascal version, and losing the assembler code.通过使用这个纯 Pascal 版本并丢失汇编代码,让您未来的生活更轻松。

This function aim is to align the storage in memory.这个 function 的目的是对齐 memory 中的存储。 It is perfectly pointless in modern Intel/AMD CPUs .在现代 Intel/AMD CPU 中完全没有意义 It may have had a benefit on a 8086 CPU, but not any more.它可能对 8086 CPU 有好处,但现在没有了。 Sounds definitively like wrong/premature optimization.听起来绝对像是错误/过早的优化。

This whole alignment subroutine may just be avoided: it would make code cleaner and also faster.可以避免整个 alignment 子例程:它会使代码更清晰,也更快。 Just get rid of TVersionizedPointerStorage and only use TVersionizedPointer .只需摆脱TVersionizedPointerStorage并仅使用TVersionizedPointer

Not aligning the data will be faster, since you won't need to compute any alignment any more, and you would just use the needed memory, whereas TVersionizedPointerStorage is always using twice the size, so it pollutes the CPU L1 cache for no benefit, and add unneeded memory allocation.不对齐数据会更快,因为您不再需要计算任何 alignment,您只需使用所需的 memory,而TVersionizedPointerStorage始终使用两倍大小,因此它会污染 CPU L1 缓存而无济于事,并添加不需要的 memory 分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM