0

I'm working with Delphi and Assembly, so, i had a problem. 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. But it's ok, i get it with Delphi Integer variables. But now, i need to join those variables in 1 of 64-bits. 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. Somebody can help me?

PRVS
  • 1,612
  • 4
  • 38
  • 75
Victor Melo
  • 188
  • 1
  • 13

2 Answers2

10

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.

Combining 46523 and 1236 should not yield 465231236. That is the wrong answer. Instead, you want to take the high order 32 bits, and put them alongside the low order 32 bits.

You are combining $0000B5BB and $00004D4. The correct answer is either $0000B5BB00004D4 or $00004D40000B5BB, depending on which of the two values are the high and low order parts.

Implement this in code, for instance, using 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.

So, bits 0 to 31 are set to the value of Lo, and bits 32 to 63 are set to the value of 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. Since the RDTSC places the values in those exact registers (not a coincidence by the way), you have nothing more to do.

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
6

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

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73