2015-11-14 9 views
0

Я работаю с Delphi и Assembly, поэтому у меня возникла проблема. Я использовал инструкцию (RDTSC) в сборке для получения метки времени считывания в 64 бита, инструкция поместила номера отдельно в два регистра EAX и EDX. Но все в порядке, я получаю его с переменными Delphi Integer. Но теперь мне нужно объединить эти переменные в 1 из 64 бит. Это как:Delphi - join 2 integer in Int64

Var1 = 46523 
var2 = 1236 

Поэтому мне нужно, чтобы поместить его в одну переменную как:

Var3 = 465231236 

это как StrCat, но я не знаю, как это сделать. Кто-нибудь может мне помочь?

+1

'(46523 << 32) | 1236' не равен 465231236. – Michael

+0

Ваш вопрос и ваш образец не совпадают. – vladon

ответ

10

Вы, разумеется, не хотите конкатенировать представления десятичных строк двух значений. Это не так, как вы ожидаете, чтобы объединить два 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.

6

Простой способ заключается в использовании рекордной

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

и вы можете хранить/читать каждое значение, как вам нравится

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; 

см: Docwiki: Variant Parts in Records