News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Help on converting Pascal to MASM

Started by Arroso, January 27, 2005, 04:13:17 PM

Previous topic - Next topic

Arroso

Hi to everybody
I'm trying (unsuccessfully) to convert in MASM some Pascal code. It's a routine that calculates the CRC32.
There are some methods of casting in Pascal, namely the Byte() and the LongInt(), that drive me insane.
The Byte() is suppose to catch the high-order byte of a Long Integer. I assume then it should be the leftmost
byte of a register (ie say eax holds 12345678h should be the byte holding 12h).
The LongInt() thing, that i ignore, according to the Byte() logic could be i guess something like

movzx eax,a_byte
shl eax,24

or not?!??

Will appreciate any hints


The following are the original Pascal source (coded by SWAG SUPPORT TEAM)


Unit CRC32c;
Interface
  Const
    CRCSeed = $ffffffff;
    CRC32tab : Array[0..255] of LongInt = (
      $00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f,
      $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988,
       ............. );

Function CRC32(value: Byte; crc: LongInt) : LongInt;
Function CRCend( crc : LongInt ) : LongInt ;

Implementation

Function  CRC32(value: Byte; crc: LongInt) : LongInt;
begin
  CRC32 := CRC32tab[Byte(crc xor LongInt(value))] xor
           ((crc shr 8) and $00ffffff);
end;
end.

Function CRCend( crc : LongInt ): LongInt;
begin
  CRCend := (crc xor CRCSeed);
end;

{ With a LongInt Variable, say vCRC32, first seed it }
  vCRC32 := CRCSeed;
{ Then go Byte-by-Byte thorugh to calculate: }
  For P := 1 to Size DO
    vCRC32 := CRC32(Bytes[P], vCRC32);

{ Then finish it off With CRCend }
    vCRC32 := CRCend(vCRC32);


...and my miserable attempt  :D


CRC32 PROC

LOCAL idx:DWORD

mov vCRC32,0FFFFFFFFh                      ; seed it

push ebx
push esi
push edi

xor ecx,ecx
mov idx,0

mov esi,hFileMem                           ; the pointer to the source buffer
mov edi,offset CRC32tab                     ; the pointer to the doubleword array

.WHILE TRUE
xor eax,eax
mov cl,BYTE PTR[esi]
mov al,cl
shl eax,24
PrintHex eax, " LongInt(value)"
push vCRC32
push vCRC32
pop ebx
xor ebx,eax
PrintHex ebx, " crc xor LongInt(value)"
shr ebx,24
PrintHex ebx, " Byte(...)"
mov eax,[edi+ebx]
PrintHex eax, " CRC32tab[...]"
pop ecx
shr ecx,8
and ecx,00ffffffh
xor eax,ecx
mov vCRC32,eax
PrintHex eax, " (crc shr 8) and 00ffffffh"
inc idx
mov ebx,hFlen
inc esi
.BREAK .IF (idx > ebx)
.ENDW

mov edx, crcseed
xor eax,edx
mov vCRC32,eax
pop edi
pop esi
pop ebx
ret

CRC32 ENDP

fallenhobbit

my quick guess would be that you are hitting a big-endian vs. little-endian problem. Have a look at this: http://www.webopedia.com/TERM/b/big_endian.html

dsouza123

The byte function, type conversion, gets the lowest order byte of the conversion.

crc := $12345678;  a longint  32 bit signed integer
b   := byte(crc);   a byte    8 bit unsigned integer

after the conversion b is $78

mov eax,012345678h
mov  bl,al


Arroso

#3
Thank you for the hint!
In your reply you specified the type Longint as a 32 bit signed integer.
For me to cast a byte to a doubleword as with the LongInt() does it means that I have to


mov al,10h
movsx ebx,al


rather than


mov al,10h
movzx ebx,al


???

dsouza123

You want the  movzx 
the pascal code should have used longword or cardinal (both 32 bit unsigned integers, equivalent to a dword)
but it lets longint work for some reason (maybe it exploits a feature/bug in the compiler).

This is a very simple (unoptimized) translation of the pascal code
using some of your assembly code.  I haven't tested it though.

  mov eax,0FFFFFFFFh

  mov crcseed,eax
  mov vCRC32,eax               ; seed it

CRC32   PROC
LOCAL idx:DWORD

  push ebx
  push esi
  push edi

  mov idx,0

  mov esi,hFileMem              ; the pointer to the source buffer
  mov edi,offset CRC32tab       ; the pointer to the doubleword array

.WHILE TRUE
  mov ecx,vCRC32
  shr ecx,8
  and ecx,0FFFFFFh
 
  mov eax,vCRC32
  movzx edx,BYTE PTR[esi]
  xor eax,edx
  and eax,0FFh
 
  xor ecx,[edi + eax*4]
  mov vCRC32,ecx
 
  inc idx
  mov eax,hFlen
.BREAK .IF (idx > eax)
  inc esi
.ENDW

  mov eax, vCRC32
  xor eax, crcseed
  mov vCRC32,eax
 
  pop edi
  pop esi
  pop ebx
  ret
CRC32   ENDP

Arroso