Reputation: 91
I'm using the following function to swap a (un)signed 64-bit integer value:
function Swap64(I: Int64): Int64;
begin
Int64Rec(Result).Bytes[0] := Int64Rec(I).Bytes[7];
Int64Rec(Result).Bytes[1] := Int64Rec(I).Bytes[6];
Int64Rec(Result).Bytes[2] := Int64Rec(I).Bytes[5];
Int64Rec(Result).Bytes[3] := Int64Rec(I).Bytes[4];
Int64Rec(Result).Bytes[4] := Int64Rec(I).Bytes[3];
Int64Rec(Result).Bytes[5] := Int64Rec(I).Bytes[2];
Int64Rec(Result).Bytes[6] := Int64Rec(I).Bytes[1];
Int64Rec(Result).Bytes[7] := Int64Rec(I).Bytes[0];
end;
How can I do the same thing in ASM to make it faster?
Upvotes: 3
Views: 1509
Reputation: 613511
You can use the bswap
instruction to swap bytes. For 32 code, you need to swap the bytes 32 bits at a time, with two uses of bswap
. For 64 bit code, you can operate on a 64 bit register directly, and swap all 8 bytes with one use of bswap
.
Here is a function for both 32 and 64 bit targets:
function ByteSwap64(Value: Int64): Int64;
asm
{$IF Defined(CPUX86)}
mov edx, [ebp+$08]
mov eax, [ebp+$0c]
bswap edx
bswap eax
{$ELSEIF Defined(CPUX64)}
mov rax, rcx
bswap rax
{$ELSE}
{$Message Fatal 'ByteSwap64 has not been implemented for this architecture.'}
{$ENDIF}
end;
I cannot say whether or not this function will lead to any discernible performance benefit. Before optimising code, you should identify bottlenecks by profiling and timing your code.
Upvotes: 5
Reputation: 27493
For 32-bit compiler:
function Swap64(I: Int64): Int64;
asm
MOV EDX,I.Int64Rec.Lo
BSWAP EDX
MOV EAX,I.Int64Rec.Hi
BSWAP EAX
end;
Upvotes: 4