Delphi的_trunc函数如何工作以及如何重新编程?

时间:2014-01-26 17:51:02

标签: delphi

我想知道Delphi(32位)中的_trunc函数是如何工作的。 我知道签名和未签名的标志以及完成这种操作的转换操作,但我还不知道并理解它的使用。 那么_trunc函数如何工作以及如何重新编程/重新编程呢? 我指的是这种类型:http://docwiki.embarcadero.com/Libraries/en/System.Trunc

1 个答案:

答案 0 :(得分:1)

Trunc函数是intrinsic。它非常有趣,因为它使用非标准的调用约定。

可以在System单元中找到它的x86实现,如下所示:

procedure _Trunc;
asm
        { ->    FST(0)  Extended argument       }
        { <-    EDX:EAX Result                  }

        SUB     ESP,12
        FNSTCW  [ESP].Word          // save
        FNSTCW  [ESP+2].Word        // scratch
        FWAIT
        OR      [ESP+2].Word, $0F00  // trunc toward zero, full precision
        FLDCW   [ESP+2].Word
        FISTP   qword ptr [ESP+4]
        FWAIT
        FLDCW   [ESP].Word
        POP     ECX
        POP     EAX
        POP     EDX
end;

虽然它被声明为没有参数的过程,但它在ST(0)中接收其输入参数,并在注释中以EDX:EAX返回结果。

我不是那个实现的忠实粉丝,会这样写:

procedure _Trunc;
const
  CW: Word=$1F3F; // trunc toward zero, full precision, mask all exceptions
var
  SaveCW: Word;
  Result: record
    Lo, Hi: Integer;
  end;
asm
  { ->    FST(0)  Extended argument       }
  { <-    EDX:EAX Result                  }
  FSTCW   SaveCW   // save
  FLDCW   CW
  FISTP   Result
  FLDCW   SaveCW   // restore
  FWAIT            // raise any exceptions
  MOV     EAX, Result.Lo
  MOV     EDX, Result.Hi
end;