简体   繁体   English

Delphi-在Int64中加入2个整数

[英]Delphi - join 2 integer in a Int64

I'm working with Delphi and Assembly , so, i had a problem. 我正在使用DelphiAssembly ,所以我遇到了问题。 I used a instruction( RDTSC ) in Assembly of getting a 64-bits read time-stamp, the instruction put the numbers separately in two registers EAX and EDX . 我在汇编中使用了一个指令( RDTSC )来获取64位读取时间戳,该指令将数字分别放在两个寄存器EAXEDX But it's ok, i get it with Delphi Integer variables. 没关系,我可以用Delphi Integer变量得到它。 But now, i need to join those variables in 1 of 64-bits. 但是现在,我需要以64位中的1个加入这些变量。 It's like: 就像是:

Var1 = 46523
var2 = 1236

So i need to put it into one variable like: 因此,我需要将其放入一个变量中,例如:

Var3 = 465231236

it's like a StrCat, but i'm don't know how to do it. 它就像一个StrCat,但我不知道该怎么做。 Somebody can help me? 有人可以帮助我吗?

You certainly don't want to concatenate the decimal string representations of the two values. 您当然不想连接两个值的十进制字符串表示形式。 That is not the way you are expected to combine the two 32 bit values returned from RTDSC into a 64 bit value. 这不是将RTDSC返回的两个32位值RTDSC为64位值的方式。

Combining 46523 and 1236 should not yield 465231236. That is the wrong answer. 将46523和1236结合使用不会得出465231236。这是错误的答案。 Instead, you want to take the high order 32 bits, and put them alongside the low order 32 bits. 相反,您希望采用高阶32位,并将它们与低阶32位并排放置。

You are combining $0000B5BB and $00004D4 . 您正在组合$0000B5BB$00004D4 The correct answer is either $0000B5BB00004D4 or $00004D40000B5BB , depending on which of the two values are the high and low order parts. 正确答案是$0000B5BB00004D4$00004D40000B5BB ,这取决于两个值中的哪一个是高阶和低阶部分。

Implement this in code, for instance, using Int64Rec : 例如,使用Int64Rec在代码中实现:

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

where Lo and Hi are the low and high 32 bit values returned by RTDSC . 其中LoHiRTDSC返回的低32位值和高32位值。

So, bits 0 to 31 are set to the value of Lo , and bits 32 to 63 are set to the value of Hi . 因此,将位0到31设置为Lo的值,将位32到63设置为Hi的值。

Or it can be written using bitwise operations: 或者可以使用按位操作来编写它:

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

If all you need to do is read the time stamp counter, then you don't need to do any of this though. 如果您需要做的只是读取时间戳计数器,那么您无需执行任何操作。 You can implement the function like this: 您可以实现如下功能:

function TimeStampCounter: UInt64;
asm
  RDTSC
end;

The register calling convention requires that a 64 bit value return value is passed back to the caller in EDX:EAX . 寄存器调用约定要求将64位值的返回值传递回EDX:EAX的调用方。 Since the RDTSC places the values in those exact registers (not a coincidence by the way), you have nothing more to do. 由于RDTSC将值放置在这些确切的寄存器中(顺便说一句,不是巧合),因此您无需执行其他操作。

All of this said, rather than using the time stamp counter, it is usually preferable to use the performance counter, which is wrapped by TStopWatch from System.Diagnostics . TStopWatch ,通常最好使用性能计数器,而不是使用时间戳计数器,性能计数器由System.DiagnosticsTStopWatch包装。

The simple way is to use a record 简单的方法是使用记录

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

and you can store/read each value as you like 您可以根据需要存储/读取每个值

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;

see: Docwiki: Variant Parts in Records 请参阅: Docwiki:记录中的变体部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM