![]() |
Byte Array to UInt64
Ich komm einfach nicht drauf.
Ich habe ein Array[0..7] of Byte und will es in ein UInt64 wandeln. Jedoch kommt immer Blödsinn raus. Auch dieser Versuch scheitert:
Delphi-Quellcode:
Auch mit einem manuellen SHL schaffe es nicht.
Type
TUInt64Rec = packed record case Integer of 1 : (_Byte : Array[0..7] of Byte); 2 : (_UInt64 : UInt64); end; Da sollte ich ja byte[0] um 56 bit, byte[1] um 48 Bit usw shiften. Das lässt mich Delphi aber nicht. Er erlaubt mir maximal 40 Bit mit SHL. ?? Beipspiel: Im Byte Array von 0..7: 00 00 00 02 00 0E 8C 19 Ergebins von Delphi: 1840861740884033536 Sollte aber sein: 8590887961 |
AW: Byte Array to UInt64
Du musst die Reihenfolge der Bytes umdrehen:
Im Byte Array von 0..7: 19 8C 0E 00 02 00 00 00 Auf Intel-Prozessoren steht das niederwertigste Byte vorn ( ![]() |
AW: Byte Array to UInt64
Stimmt! Das spuckt der Windows Rechner auch aus.
Und wie macht man das am besten? Edit: Habe das gefunden:
Delphi-Quellcode:
Geht und passt jetzt!
procedure SwapUInt64(var X: UInt64);
asm mov EBX,dword ptr [X] mov ECX,dword ptr [X+4] bswap EBX bswap ECX mov [X],dword ptr ECX mov [X+4],dword ptr EBX end; |
AW: Byte Array to UInt64
Wow, danke Uwe. Ich habe bisher noch nicht das deutsche Wort für "Endianess" gekannt. Wieder etwas gelernt :thumb:
|
AW: Byte Array to UInt64
Jetzt habe ich doch noch ein Problem mit der SwapUInt64 festgestellt.
Wenn ich bei der Debug Version das Optimieren ausschalte geht sie. Wenn ich für das Release das Optimieren einschalte werden andere Speicherbereiche Überschrieben und es kommt zum Absturz. Gibt es dann dazu noch eine andere Möglichkeit? |
AW: Byte Array to UInt64
EBX darf niemals verändert werden
Entweder ihr nehmt was Anderers (EAX EDX ECX ESI EDI) oder der Wert von EBX muß gesichert und danach dann wiederhergestellt werden. PS: EAX ist schon belegt mit X :angle2: Ich würde auch empfehlen statt X direkt EAX zu nehmen, nicht daß Delphi noch auf die Idee kommt einen Stackframe zu erstellen. |
AW: Byte Array to UInt64
Delphi-Quellcode:
Dies macht nun keine Probleme mehr :thumb:
function SwapUInt64(X: UInt64): UInt64;
asm mov EDX,dword ptr [X] mov EAX,dword ptr [X+4] bswap EDX bswap EAX end; |
AW: Byte Array to UInt64
Jetzt nocheinmal dazu:
warum geht das nicht:
Delphi-Quellcode:
function TUInt64Rec2.GetUInt64 : UInt64;
begin Result := (_Byte[0] Shl 56) or (_Byte[1] Shl 48) or (_Byte[2] Shl 40) or (_Byte[3] Shl 32) or (_Byte[4] Shl 24) or (_Byte[5] Shl 16) or (_Byte[6] Shl 8) or _Byte[7]; end; Zitat:
Edit: Es scheint an shl zu liegen. So geht es:
Delphi-Quellcode:
function TUInt64Rec2.GetUInt64 : UInt64;
var i1, i2 : UInt64; begin i1 := (_Byte[0] Shl 24) or (_Byte[1] Shl 16) or (_Byte[2] Shl 8) or _Byte[3]; i2 := (_Byte[4] Shl 24) or (_Byte[5] Shl 16) or (_Byte[6] Shl 8) or _Byte[7]; Result := (i1 shl 32) or i2; end; |
AW: Byte Array to UInt64
Ich vermute mal, es liegt daran, daß der Compiler kein 64-Bit-Register zur Verfügung hat, in dem er die Shift-Operation durchführen kann.
Laut Hilfe arbeiten die logischen Operatoren auch lediglich auf (32-Bit) Integer. |
AW: Byte Array to UInt64
Zitat:
Delphi-Quellcode:
function TUInt64Rec2.GetUInt64 : UInt64;
begin Result := (uint64(_Byte[0]) Shl 56) or (uint64(_Byte[1]) Shl 48) or (uint64(_Byte[2]) Shl 40) or (uint64(_Byte[3]) Shl 32) or (_Byte[4] Shl 24) or (_Byte[5] Shl 16) or (_Byte[6] Shl 8) or _Byte[7]; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz