【问题标题】:Delphi - join 2 integer in a Int64Delphi - 在 Int64 中加入 2 个整数
【发布时间】:2015-11-14 19:11:19
【问题描述】:

我正在与DelphiAssembly 合作,所以,我遇到了问题。我在汇编中使用了一条指令(RDTSC)来获取 64 位读取时间戳,该指令将数字分别放在两个寄存器 EAXEDX 中。但没关系,我用Delphi Integer 变量得到它。但现在,我需要将这些变量加入 1 个 64 位中。就像:

Var1 = 46523
var2 = 1236

所以我需要将它放入一个变量中,例如:

Var3 = 465231236

它就像一个 StrCat,但我不知道该怎么做。有人可以帮助我吗?

【问题讨论】:

  • (46523 << 32) | 1236 不等于 465231236。
  • 你的问题和你的样本不一样。

标签: delphi assembly strcat rdtsc


【解决方案1】:

您当然不想连接两个值的十进制字符串表示。这不是您期望将从RTDSC 返回的两个 32 位值组合成 64 位值的方式。

结合 46523 和 1236 不应产生 465231236。这是错误的答案。相反,您希望获取高 32 位,并将它们与低 32 位放在一起。

您正在组合$0000B5BB$00004D4。正确答案是$0000B5BB00004D4$00004D40000B5BB,取决于这两个值中的哪一个是高位和低位部分。

在代码中实现这一点,例如,使用Int64Rec

var
  Value: UInt64;
...
Int64Rec(Value).Lo := Lo;
Int64Rec(Value).Hi := Hi;

其中LoHiRTDSC 返回的低和高32 位值。

因此,位 0 到 31 设置为 Lo 的值,位 32 到 63 设置为 Hi 的值。

或者可以用位运算来写:

Value := (UInt64(Hi) shl 32) or UInt64(Lo);

如果您只需要读取时间戳计数器,那么您无需执行任何操作。你可以这样实现函数:

function TimeStampCounter: UInt64;
asm
  RDTSC
end;

寄存器调用约定要求在EDX:EAX 中将一个 64 位值返回值传回给调用者。由于RDTSC 将值放在那些精确的寄存器中(顺便说一句,这不是巧合),因此您无事可做。

综上所述,通常最好使用性能计数器,而不是使用时间戳计数器,它由TStopWatch 包装在System.Diagnostics 中。

【讨论】:

    【解决方案2】:

    简单的方法是使用记录

    type
      TMyTimestamp = record
        case Boolean of
          true:
            ( Value: Int64 );
          false:
            ( Value1: Integer; Value2: Integer );
      end;
    

    您可以根据需要存储/读取每个值

    var
      ts: TMyTimestamp;
    begin
      ts.Value1 := 46523;
      ts.Value2 := 1236;
      WriteLn( ts.Value ); // -> 5308579624379
    
      ts.Value := 5308579624379;
      WriteLn( ts.Value1 ); // -> 46523
      WriteLn( ts.Value2 ); // -> 1236
    end;
    

    见:Docwiki: Variant Parts in Records

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      相关资源
      最近更新 更多