Была у меня функция, которая CRC считает. Сам я переписал ее с какого-то сайта много лет назад и вполне нормально использовал, а сейчас потребовалось избавится от asm кода (такое вот пожелание заказчика...) и перевести ее на чистую Delphi.
С ассембелером сталкивался лет 10 назад, и с тех пор уже много подзабылось
function CRC(S : String): Cardinal; var Len,crc : Cardinal; K : PChar; begin Len := Length(S); K := PChar(S); asm mov dword ptr [crc],$ffffffff @@2: dec dword ptr [len] cmp dword ptr [len],$FFFFFFFF je @@1 mov eax,dword ptr [K] movsx eax,byte ptr [eax] mov ecx,dword ptr [crc] sar ecx,$18 xor eax,ecx and eax,$000000ff mov eax,dword ptr [crctable+eax*$4] mov ecx,dword ptr [crc] shl ecx,$08 xor eax,ecx mov dword ptr [crc],eax inc dword ptr [K] jmp @@2 @@1: // NOTE: From here on the asm is optional... mov eax,dword ptr [crc] not eax // Next line strips signed bit... and eax,$7fffffff mov dword ptr [crc],eax end; Result := crc; end;
Сам алгоритм расчета CRC стандартен, его "порт" на Delphi я нашел без труда:
Function CRC2(const S: String): LongInt; var i :LongInt; newcrc :LongInt; begin newcrc:=$ffffffff; for i:=1 to Length(S) do newcrc:=(newcrc shr 8) xor crctable[(newcrc and $FF) xor ord(S[i])]; Result:=newcrc; end;
но вот значение CRC2() возвращает отличное от CRC() Есть ли знатоки асма, кто взглянув на CRC() и CRC2() сказал бы, почему именно?
Код delphi: function CRC2(const S: string): Integer; var i: Integer; begin Result := -1; for i := 1 to Length(S) do Result := Result shl 8 xor Integer(CRCTable[(Result shr $18 xor Ord(S[i])) and $FF]); Result := not Result and $7FFFFFFF; end;