Вы, разумеется, не хотите конкатенировать представления десятичных строк двух значений. Это не так, как вы ожидаете, чтобы объединить два 32-битных значения, возвращаемых с RTDSC
, в 64-битное значение.
Сочетание 46523 и 1236 не должно давать 465231236. Это неправильный ответ. Вместо этого вы хотите взять 32 бита высокого порядка и разместить их рядом с 32 битами младшего порядка.
Вы комбинируете $0000B5BB
и $00004D4
. Правильный ответ - либо $0000B5BB00004D4
, либо $00004D40000B5BB
, в зависимости от того, какое из двух значений является частями высокого и низкого порядка.
реализовать это в коде, например, с помощью Int64Rec
:
var
Value: UInt64;
...
Int64Rec(Value).Lo := Lo;
Int64Rec(Value).Hi := Hi;
, где Lo
и Hi
являются низкие и высокие 32-разрядные значения, возвращенные RTDSC
.
Итак, биты с 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
.
'(46523 << 32) | 1236' не равен 465231236. – Michael
Ваш вопрос и ваш образец не совпадают. – vladon