home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 9 Archive
/
09-Archive.zip
/
zip21.zip
/
win32
/
crc_i386.asm
next >
Wrap
Assembly Source File
|
1996-02-04
|
5KB
|
144 lines
; crc_i386.asm, optimized CRC calculation function for Zip and UnZip, not
; copyrighted by Paul Kienitz and Christian Spieler. Last revised 19 Jan 96.
;
; FLAT memory model assumed.
;
; The loop unroolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
; This results in shorter code at the expense of reduced performance.
;
;==============================================================================
;
; Do NOT assemble this source if external crc32 routine from zlib gets used.
;
IFNDEF USE_ZLIB
;
.386p
name crc_i386
.MODEL FLAT
extrn _get_crc_table:near ; ulg near *get_crc_table(void);
;
IFNDEF NO_STD_STACKFRAME
; Use a `standard' stack frame setup on routine entry and exit.
; Actually, this option is set as default, because it results
; in smaller code !!
STD_ENTRY MACRO
push ebp
mov ebp,esp
ENDM
Arg1 EQU 08H[ebp]
Arg2 EQU 0CH[ebp]
Arg3 EQU 10H[ebp]
STD_LEAVE MACRO
pop ebp
ENDM
ELSE ; NO_STD_STACKFRAME
STD_ENTRY MACRO
ENDM
Arg1 EQU 18H[esp]
Arg2 EQU 1CH[esp]
Arg3 EQU 20H[esp]
STD_LEAVE MACRO
ENDM
ENDIF ; ?NO_STD_STACKFRAME
; This is the loop body of the CRC32 cruncher.
; registers modified:
; ebx : crc value "c"
; esi : pointer to next data byte "text++"
; registers read:
; edi : pointer to base of crc_table array
; scratch registers:
; eax : requires upper three bytes of eax = 0, uses al
Do_CRC MACRO
lodsb ; al <-- *text++
xor al,bl ; (c ^ *text++) & 0xFF
shr ebx,8 ; c = (c >> 8)
xor ebx,[edi+eax*4] ; ^ table[(c ^ *text++) & 0xFF]
ENDM
_TEXT segment para
public _crc32
_crc32 proc near ; ulg crc32(ulg crc, uch *text, extent len)
STD_ENTRY
push edi
push esi
push ebx
push edx
push ecx
mov esi,Arg2 ; 2nd arg: uch *text
test esi,esi
jne short Crunch_it ;> if (!text)
sub eax,eax ;> return 0;
IFNDEF NO_STD_STACKFRAME
jmp short fine ;>
ELSE
jmp fine ;>
ENDIF
; align destination of commonly taken jump at longword boundary
align 4
Crunch_it: ;> else {
call _get_crc_table
mov edi,eax
mov ebx,Arg1 ; 1st arg: ulg crc
sub eax,eax ; eax=0; make al usable as a dword
mov ecx,Arg3 ; 3rd arg: extent textlen
not ebx ;> c = ~crc;
cld ; incr. idx regs on string ops
IFNDEF NO_UNROLLED_LOOPS
mov edx,ecx ; save textlen in edx
shr ecx,3 ; ecx = textlen / 8
and edx,000000007H ; edx = textlen % 8
jecxz No_Eights
; align loop head at start of 486 internal cache line !!
align 16
Next_Eight:
Do_CRC
Do_CRC
Do_CRC
Do_CRC
Do_CRC
Do_CRC
Do_CRC
Do_CRC
loop Next_Eight
No_Eights:
mov ecx,edx
ENDIF ; NO_UNROLLED_LOOPS
jecxz bail ;> if (textlen)
; align loop head at start of 486 internal cache line !!
align 16
loupe: ;> do {
Do_CRC ; c = CRC32(c, *text++);
loop loupe ;> } while (--textlen);
bail: ;> }
mov eax,ebx
not eax ;> return ~c;
fine:
pop ecx
pop edx
pop ebx
pop esi
pop edi
STD_LEAVE
ret
_crc32 endp
_TEXT ends
;
ENDIF ;!USE_ZLIB
;
end