Delphi XE2 64位:GraphicEx中的内联asm

Delphi XE2 64位:GraphicEx中的内联asm,delphi,assembly,delphi-xe2,basm,graphicex,Delphi,Assembly,Delphi Xe2,Basm,Graphicex,从asm到纯delphi的结果如何?我无法编译需要GraphicEx的组件,这在JPG单元中给了我一个错误,即内联汇编不支持64位 function __ftol: Integer; var f: double; begin asm lea eax, f // BC++ passes floats on the FPU stack fstp qword ptr [eax] // Delphi passes floats on t

从asm到纯delphi的结果如何?我无法编译需要GraphicEx的组件,这在JPG单元中给了我一个错误,即内联汇编不支持64位

function __ftol: Integer;
var
  f: double;
begin
  asm
    lea    eax, f             //  BC++ passes floats on the FPU stack
    fstp  qword ptr [eax]     //  Delphi passes floats on the CPU stack
  end;
  Result := Trunc(f);
end;
更新:对不起,我错了。进入此功能时,双精度计数器存储在FPU中。 然后将double放入局部变量f并截断为整数。 所以忘了我的答案吧

GraphicEx中没有使用此例程,因此请尝试对其进行注释

更新2

正如David所说,它可以被.obj文件中的链接使用。 假设它们是64位对象文件,执行相同的参数传递(FPU堆栈中的双参数), 以下是一个可以使用的函数(在64位模式下):


当您链接使用bcc32编译的.obj文件时,通常会包含ftol。这就是这里发生的事情吗?虽然GraphicsEx没有显式使用该例程,但它可能被链接到GraphicsEx单元之一的.obj文件使用。不要假设参数传递在64位中是相同的。完全不同的ABI。@David,没错,linux/GCC在32位中使用了这种类型的参数传递约定。在64位中,执行方式有所不同,请参阅
function __ftol( f : double) : Integer;
begin
  Result := Trunc(f);
end;
function __ftol : Integer;
// Assumes double value is in FPU stack on entry
// Make a truncation to integer and put it into function result
var
  TmpVal: Int64;
  SaveCW, ScratchCW: word;

asm
  .NOFRAME 

  fnstcw word ptr [SaveCW]
  fnstcw word ptr [ScratchCW]
  or word ptr [ScratchCW], 0F00h  ;// trunc toward zero, full precision
  fldcw word ptr [ScratchCW]
  fistp qword ptr [TmpVal]
  fldcw word ptr [SaveCW]
  mov rax, TmpVal
end;