home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip52.zip / win32 / crc_i386.asm < prev    next >
Assembly Source File  |  1996-02-04  |  5KB  |  144 lines

  1. ; crc_i386.asm, optimized CRC calculation function for Zip and UnZip, not
  2. ; copyrighted by Paul Kienitz and Christian Spieler.  Last revised 19 Jan 96.
  3. ;
  4. ; FLAT memory model assumed.
  5. ;
  6. ; The loop unroolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
  7. ; This results in shorter code at the expense of reduced performance.
  8. ;
  9. ;==============================================================================
  10. ;
  11. ; Do NOT assemble this source if external crc32 routine from zlib gets used.
  12. ;
  13.     IFNDEF USE_ZLIB
  14. ;
  15.         .386p
  16.         name    crc_i386
  17.         .MODEL  FLAT
  18.  
  19. extrn   _get_crc_table:near    ; ulg near *get_crc_table(void);
  20.  
  21. ;
  22.     IFNDEF NO_STD_STACKFRAME
  23.         ; Use a `standard' stack frame setup on routine entry and exit.
  24.         ; Actually, this option is set as default, because it results
  25.         ; in smaller code !!
  26. STD_ENTRY       MACRO
  27.                 push    ebp
  28.                 mov     ebp,esp
  29.         ENDM
  30.  
  31.         Arg1    EQU     08H[ebp]
  32.         Arg2    EQU     0CH[ebp]
  33.         Arg3    EQU     10H[ebp]
  34.  
  35. STD_LEAVE       MACRO
  36.                 pop     ebp
  37.         ENDM
  38.  
  39.     ELSE  ; NO_STD_STACKFRAME
  40.  
  41. STD_ENTRY       MACRO
  42.         ENDM
  43.  
  44.         Arg1    EQU     18H[esp]
  45.         Arg2    EQU     1CH[esp]
  46.         Arg3    EQU     20H[esp]
  47.  
  48. STD_LEAVE       MACRO
  49.         ENDM
  50.  
  51.     ENDIF ; ?NO_STD_STACKFRAME
  52.  
  53. ; This is the loop body of the CRC32 cruncher.
  54. ; registers modified:
  55. ;   ebx  : crc value "c"
  56. ;   esi  : pointer to next data byte "text++"
  57. ; registers read:
  58. ;   edi  : pointer to base of crc_table array
  59. ; scratch registers:
  60. ;   eax  : requires upper three bytes of eax = 0, uses al
  61. Do_CRC  MACRO
  62.                 lodsb                        ; al <-- *text++
  63.                 xor     al,bl                ; (c ^ *text++) & 0xFF
  64.                 shr     ebx,8                ; c = (c >> 8)
  65.                 xor     ebx,[edi+eax*4]      ;  ^ table[(c ^ *text++) & 0xFF]
  66.         ENDM
  67.  
  68. _TEXT   segment para
  69.  
  70.         public  _crc32
  71. _crc32          proc    near       ; ulg crc32(ulg crc, uch *text, extent len)
  72.                 STD_ENTRY
  73.                 push    edi
  74.                 push    esi
  75.                 push    ebx
  76.                 push    edx
  77.                 push    ecx
  78.  
  79.                 mov     esi,Arg2             ; 2nd arg: uch *text
  80.                 test    esi,esi
  81.                 jne     short Crunch_it      ;> if (!text)
  82.                 sub     eax,eax              ;>   return 0;
  83.     IFNDEF NO_STD_STACKFRAME
  84.                 jmp     short fine           ;>
  85.     ELSE
  86.                 jmp     fine                 ;>
  87.     ENDIF
  88. ; align destination of commonly taken jump at longword boundary
  89.                 align   4
  90. Crunch_it:                                   ;> else {
  91.                 call    _get_crc_table
  92.                 mov     edi,eax
  93.                 mov     ebx,Arg1             ; 1st arg: ulg crc
  94.                 sub     eax,eax              ; eax=0; make al usable as a dword
  95.                 mov     ecx,Arg3             ; 3rd arg: extent textlen
  96.                 not     ebx                  ;>   c = ~crc;
  97.                 cld                          ; incr. idx regs on string ops
  98.  
  99.     IFNDEF  NO_UNROLLED_LOOPS
  100.                 mov     edx,ecx              ; save textlen in edx
  101.                 shr     ecx,3                ; ecx = textlen / 8
  102.                 and     edx,000000007H       ; edx = textlen % 8
  103.                 jecxz   No_Eights
  104. ; align loop head at start of 486 internal cache line !!
  105.                 align   16
  106. Next_Eight:
  107.                 Do_CRC
  108.                 Do_CRC
  109.                 Do_CRC
  110.                 Do_CRC
  111.                 Do_CRC
  112.                 Do_CRC
  113.                 Do_CRC
  114.                 Do_CRC
  115.                 loop    Next_Eight
  116. No_Eights:
  117.                 mov     ecx,edx
  118.     ENDIF ; NO_UNROLLED_LOOPS
  119.                 jecxz   bail                 ;>   if (textlen)
  120. ; align loop head at start of 486 internal cache line !!
  121.                 align   16
  122. loupe:                                       ;>     do {
  123.                 Do_CRC                       ;        c = CRC32(c, *text++);
  124.                 loop    loupe                ;>     } while (--textlen);
  125.  
  126. bail:                                        ;> }
  127.                 mov     eax,ebx
  128.                 not     eax                  ;> return ~c;
  129. fine:
  130.                 pop     ecx
  131.                 pop     edx
  132.                 pop     ebx
  133.                 pop     esi
  134.                 pop     edi
  135.                 STD_LEAVE
  136.                 ret
  137. _crc32          endp
  138.  
  139. _TEXT   ends
  140. ;
  141.     ENDIF ;!USE_ZLIB
  142. ;
  143. end
  144.