Search code examples
delphiassemblystrcatrdtsc

Delphi - join 2 integer in a Int64


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?


Solution

  • 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.