2015-11-07 117 views
3

我使用下面的函數來交換(未)符號的64位整型值:快速Swap64功能在Delphi

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; 

我如何做同樣的事情在ASM,使其更快?

+0

無論哪種情況,都可以使用'bswap'指令。 – Jester

回答

2

對於32位編譯器:

function Swap64(I: Int64): Int64; 
asm 
     MOV  EDX,I.Int64Rec.Lo 
     BSWAP EDX 
     MOV  EAX,I.Int64Rec.Hi 
     BSWAP EAX 
end; 
4

可以使用bswap指令交換字節。對於32位代碼,您需要一次交換32位字節,並使用bswap兩次。對於64位代碼,您可以直接在64位寄存器上操作,並將所有8個字節交換爲bswap

下面是32位和64位的目標函數:

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; 

我不能說這個功能是否會導致任何明顯的性能優勢。在優化代碼之前,您應該通過對代碼進行分析和計時來識別瓶頸。

+1

'CPUX86'指令在Delphi XE2中引入,所以'CPU386'是最好的。 – kludg

+0

@用戶真的很依賴。如果你不需要支持這樣的舊版本,那麼它就沒有問題。提問者沒有說明一個版本。如果提問者使用pre XE2版本,則根本不需要條件。 –

+0

我根本不熟悉Delphi ASM,但不應該在觸摸它們之前將這些寄存器放在堆棧上?或者一個函數在啓動時執行完整的寄存器推送? – Blindy