我正在使用Delphi
和Assembly
,因此,我遇到了问题。我在汇编中使用了一条指令(RDTSC
)获取64位读取时间戳,该指令将数字分别放在两个寄存器EAX
和EDX
中。但没关系,我用Delphi Integer
变量得到它。但现在,我需要将这些变量加入64位中的1位。它就像:
Var1 = 46523
var2 = 1236
所以我需要把它放在一个变量中:
Var3 = 465231236
它就像一个StrCat,但我不知道该怎么做。有人可以帮帮我吗?
答案 0 :(得分:10)
您当然不希望连接两个值的十进制字符串表示形式。这不是您希望将从RTDSC
返回的两个32位值组合成64位值的方式。
组合46523和1236不应该产生465231236.这是错误的答案。相反,您希望采用高位32位,并将它们放在低位32位旁边。
您正在合并$0000B5BB
和$00004D4
。正确答案是$0000B5BB00004D4
或$00004D40000B5BB
,具体取决于这两个值中的哪一个是高阶和低阶部分。
在代码中实现此功能,例如,使用Int64Rec
:
var
Value: UInt64;
...
Int64Rec(Value).Lo := Lo;
Int64Rec(Value).Hi := Hi;
其中Lo
和Hi
是RTDSC
返回的低32位值和高32位值。
因此,位0到31被设置为Lo
的值,位32到63被设置为Hi
的值。
或者可以使用按位运算编写:
Value := (UInt64(Hi) shl 32) or UInt64(Lo);
如果您只需要读取时间戳计数器,那么您不需要执行任何操作。你可以实现这样的功能:
function TimeStampCounter: UInt64;
asm
RDTSC
end;
寄存器调用约定要求将64位值返回值传递回EDX:EAX
中的调用方。由于RDTSC
将值放在那些精确的寄存器中(顺便说一下不是巧合),因此您无需再做任何事情了。
所有这些都说,不是使用时间戳计数器,通常最好使用性能计数器,它由TStopWatch
System.Diagnostics
包裹。
答案 1 :(得分:6)
简单的方法是使用记录
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;