Delphi中的RolDWord实现(32位和64位)?

时间:2015-09-11 20:46:02

标签: delphi

根据 http://www.freepascal.org/docs-html/rtl/system/roldword.html

RolDWord向左旋转一个4字节的int(Free Pascal)。

Delphi中有RolDWord吗?

2 个答案:

答案 0 :(得分:6)

您可以使用以下功能:

function rolw(Value: Word; N: Integer): Word;
asm
{$IF Defined(CPUX86)}
  MOV  CL, DL
  ROL  AX, CL
{$ELSEIF Defined(CPUX64)}
  MOV  AX, CX
  MOV  CL, DL
  ROL  AX, CL
{$ELSE}
{$Message Fatal 'rolw has not been implemented for this architecture.'}
{$ENDIF}
end;

function rorw(Value: Word; N: Integer): Word;
asm
{$IF Defined(CPUX86)}
  MOV  CL, DL
  ROR  AX, CL
{$ELSEIF Defined(CPUX64)}
  MOV  AX, CX
  MOV  CL, DL
  ROR  AX, CL
{$ELSE}
{$Message Fatal 'rorw has not been implemented for this architecture.'}
{$ENDIF}
end;

function roldw(Value: Cardinal; N: Integer): Cardinal;
asm
{$IF Defined(CPUX86)}
  MOV  CL, DL
  ROL  EAX, CL
{$ELSEIF Defined(CPUX64)}
  MOV  EAX, ECX
  MOV  CL, DL
  ROL  EAX, CL
{$ELSE}
{$Message Fatal 'roldw has not been implemented for this architecture.'}
{$ENDIF}
end;

function rordw(Value: Cardinal; N: Integer): Cardinal;
asm
{$IF Defined(CPUX86)}
  MOV  CL, DL
  ROR  EAX, CL
{$ELSEIF Defined(CPUX64)}
  MOV  EAX, ECX
  MOV  CL, DL
  ROR  EAX, CL
{$ELSE}
{$Message Fatal 'rordw has not been implemented for this architecture.'}
{$ENDIF}
end;

然而,正如JohanLU RD指出的那样,内联Pascal版本是可移植的,并且通常对于此功能更快,因为内联对于如此小的功能非常重要。

看起来像这样:

{$IFOPT Q+}{$DEFINE OVERFLOWCHECKSON}{$ENDIF}
{$Q-}    
function rolw_pas(Value: Word; N: Integer): Word; inline;
begin
  Result:= ((Value shl N) and $ffff) or (Value shr (16-N));
end;

function rorw_pas(Value: Word; N: Integer): Word; inline;
begin
  Result:= (Value shr N) or ((Value shl (16-N)) and $ffff);
end;

function roldw_pas(Value: Cardinal; N: Integer): Cardinal; inline;
begin
  Result:= (Value shl N) or (Value shr (32-N));
end;

function rordw_pas(Value: Cardinal; N: Integer): Cardinal; inline;
begin
  Result:= (Value shr N) or (Value shl (32-N));
end;
{$IFDEF OVERFLOWCHECKSON}{$Q+}{$ENDIF}

请注意,我们确实需要确保禁用溢出检查。

答案 1 :(得分:3)

在purepascal中,您可以按如下方式使用班次。

function rolw(input: dword; shift: cardinal): dword; inline;
begin
  Result:= (input shl shift) or (input shr (32-shift));
end;

RorW的工作方式完全相同。

<强>优势
它适用于任何版本的Delphi,包括移动编译器。

asm代码实际上更慢,因为它无法内联,根据LURD的时间(在他的系统和他的输入数据上)纯粹的pascal版本在x86上快3.5倍,在x64上快25%。但是对于不同的输入数据,时序可能完全不同,因此如果性能是一个驱动因素,请确保使用代表您实际问题的数据进行基准测试。

源更短,因为不同的CPU类型不需要不同的版本。

如果你有一个更大的asm块,请使用ror / rol指令;它们具有与移位指令完全相同的延迟,但是在1条指令中执行的操作不是3。