Delphi - 在 Int64 中加入 2 个整数
Delphi - join 2 integer in a Int64
我正在与 Delphi
和 Assembly
合作,所以我遇到了问题。我在获取64位读取时间戳的汇编中使用了一条指令(RDTSC
),该指令将数字分别放在两个寄存器EAX
和EDX
中。但没关系,我用 Delphi Integer
变量得到它。但是现在,我需要将这些变量加入 64 位之一。就像:
Var1 = 46523
var2 = 1236
所以我需要将它放入一个变量中,例如:
Var3 = 465231236
它就像一个 StrCat,但我不知道该怎么做。有人可以帮助我吗?
您当然不想连接两个值的十进制字符串表示形式。这不是您期望将 RTDSC
中的两个 32 位值 return 组合成 64 位值的方式。
组合 46523 和 1236 不应产生 465231236。这是错误的答案。相反,您想要获取高位 32 位,并将它们与低位 32 位放在一起。
您正在组合 [=14=]00B5BB
和 [=15=]004D4
。正确答案是 [=16=]00B5BB00004D4
或 [=17=]004D40000B5BB
,具体取决于两个值中的哪个是高阶部分和低阶部分。
在代码中实现,例如,使用 Int64Rec
:
var
Value: UInt64;
...
Int64Rec(Value).Lo := Lo;
Int64Rec(Value).Hi := Hi;
其中 Lo
和 Hi
是由 RTDSC
编辑的低 32 位值和高 32 位值 return。
因此,位 0 到 31 被设置为 Lo
的值,而位 32 到 63 被设置为 Hi
的值。
或者用位运算也可以写成:
Value := (UInt64(Hi) shl 32) or UInt64(Lo);
如果您需要做的只是读取时间戳计数器,那么您不需要执行任何这些操作。您可以像这样实现该功能:
function TimeStampCounter: UInt64;
asm
RDTSC
end;
寄存器调用约定要求将 64 位值 return 值传回给 EDX:EAX
中的调用者。由于 RDTSC
将值放在那些确切的寄存器中(顺便说一句,这不是巧合),您无事可做。
综上所述,与其使用时间戳计数器,不如使用由 TStopWatch
from System.Diagnostics
包装的性能计数器通常更可取。
简单的方法就是使用一条记录
type
TMyTimestamp = record
case Boolean of
true:
( Value: Int64 );
false:
( Value1: Integer; Value2: Integer );
end;
您可以 store/read 每个值都随心所欲
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;
我正在与 Delphi
和 Assembly
合作,所以我遇到了问题。我在获取64位读取时间戳的汇编中使用了一条指令(RDTSC
),该指令将数字分别放在两个寄存器EAX
和EDX
中。但没关系,我用 Delphi Integer
变量得到它。但是现在,我需要将这些变量加入 64 位之一。就像:
Var1 = 46523
var2 = 1236
所以我需要将它放入一个变量中,例如:
Var3 = 465231236
它就像一个 StrCat,但我不知道该怎么做。有人可以帮助我吗?
您当然不想连接两个值的十进制字符串表示形式。这不是您期望将 RTDSC
中的两个 32 位值 return 组合成 64 位值的方式。
组合 46523 和 1236 不应产生 465231236。这是错误的答案。相反,您想要获取高位 32 位,并将它们与低位 32 位放在一起。
您正在组合 [=14=]00B5BB
和 [=15=]004D4
。正确答案是 [=16=]00B5BB00004D4
或 [=17=]004D40000B5BB
,具体取决于两个值中的哪个是高阶部分和低阶部分。
在代码中实现,例如,使用 Int64Rec
:
var
Value: UInt64;
...
Int64Rec(Value).Lo := Lo;
Int64Rec(Value).Hi := Hi;
其中 Lo
和 Hi
是由 RTDSC
编辑的低 32 位值和高 32 位值 return。
因此,位 0 到 31 被设置为 Lo
的值,而位 32 到 63 被设置为 Hi
的值。
或者用位运算也可以写成:
Value := (UInt64(Hi) shl 32) or UInt64(Lo);
如果您需要做的只是读取时间戳计数器,那么您不需要执行任何这些操作。您可以像这样实现该功能:
function TimeStampCounter: UInt64;
asm
RDTSC
end;
寄存器调用约定要求将 64 位值 return 值传回给 EDX:EAX
中的调用者。由于 RDTSC
将值放在那些确切的寄存器中(顺便说一句,这不是巧合),您无事可做。
综上所述,与其使用时间戳计数器,不如使用由 TStopWatch
from System.Diagnostics
包装的性能计数器通常更可取。
简单的方法就是使用一条记录
type
TMyTimestamp = record
case Boolean of
true:
( Value: Int64 );
false:
( Value1: Integer; Value2: Integer );
end;
您可以 store/read 每个值都随心所欲
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;