home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zip22.zip / win32 / match32.asm < prev    next >
Assembly Source File  |  1996-12-14  |  6KB  |  152 lines

  1. ;
  2. ; Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  3. ; Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko.
  4. ; Permission is granted to any individual or institution to use, copy, or
  5. ; redistribute this software so long as all of the original files are included,
  6. ; that it is not sold for profit, and that this copyright notice is retained.
  7. ;
  8. ; match32.asm by Jean-loup Gailly.
  9.  
  10. ; match32.asm, optimized version of longest_match() in deflate.c
  11. ; To be used only with 32 bit flat model. To simplify the code, the option
  12. ; -DDYN_ALLOC is not supported.
  13. ; This file is only optional. If you don't have an assembler, use the
  14. ; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o
  15. ; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
  16. ; assembled with an equivalent -DWSIZE=<whatever>.
  17. ;
  18. ; Win32 (Windows NT) version - 1994/04/13 by Steve Salisbury
  19. ; * works with Microsoft MASM 6.1X and Microsoft Visual C++ / 32-bit edition
  20.  
  21.         .386p
  22.  
  23.         name    match
  24.         .MODEL  FLAT
  25.  
  26. _BSS    segment
  27.         extrn   _match_start  : dword
  28.         extrn   _prev_length  : dword
  29.         extrn   _good_match   : dword
  30.         extrn   _strstart     : dword
  31.         extrn   _max_chain_length : dword
  32.         extrn   _prev         : word
  33.         extrn   _window       : byte
  34. _BSS    ends
  35.  
  36. _TEXT   segment
  37.         public  _match_init
  38.         public  _longest_match
  39.  
  40.     ifndef      WSIZE
  41.         WSIZE         equ 32768         ; keep in sync with zip.h !
  42.     endif
  43.         MIN_MATCH     equ 3
  44.         MAX_MATCH     equ 258
  45.         MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
  46.         MAX_DIST      equ (WSIZE-MIN_LOOKAHEAD)
  47.  
  48. ; initialize or check the variables used in match.asm.
  49.  
  50. _match_init proc near
  51.         ret
  52. _match_init endp
  53.  
  54. ; -----------------------------------------------------------------------
  55. ; Set match_start to the longest match starting at the given string and
  56. ; return its length. Matches shorter or equal to prev_length are discarded,
  57. ; in which case the result is equal to prev_length and match_start is
  58. ; garbage.
  59. ; IN assertions: cur_match is the head of the hash chain for the current
  60. ;   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  61.  
  62. ; int longest_match(cur_match)
  63.  
  64. _longest_match proc near
  65.  
  66.         cur_match    equ dword ptr [esp+20]
  67.         ; return address                ; esp+16
  68.         push    ebp                     ; esp+12
  69.         push    edi                     ; esp+8
  70.         push    esi                     ; esp+4
  71.         push    ebx                     ; esp
  72.  
  73. ;       match        equ esi
  74. ;       scan         equ edi
  75. ;       chain_length equ ebp
  76. ;       best_len     equ ebx
  77. ;       limit        equ edx
  78.  
  79.         mov     esi,cur_match
  80.         mov     ebp,_max_chain_length   ; chain_length = max_chain_length
  81.         mov     edi,_strstart
  82.         mov     edx,edi
  83.         sub     edx,MAX_DIST            ; limit = strstart-MAX_DIST
  84.         jae     short limit_ok
  85.         sub     edx,edx                 ; limit = NIL
  86. limit_ok:
  87.         add     edi,2+offset _window    ; edi = offset(window + strstart + 2)
  88.         mov     ebx,_prev_length        ; best_len = prev_length
  89.         mov     ax,[ebx+edi-3]          ; ax = scan[best_len-1..best_len]
  90.         mov     cx,[edi-2]              ; cx = scan[0..1]
  91.         cmp     ebx,_good_match         ; do we have a good match already?
  92.         jb      do_scan
  93.         shr     ebp,2                   ; chain_length >>= 2
  94.         jmp     short do_scan
  95.  
  96.         align   4                       ; align destination of branch
  97. long_loop:
  98. ; at this point, edi == scan+2, esi == cur_match
  99.         mov     ax,[ebx+edi-3]          ; ax = scan[best_len-1..best_len]
  100.         mov     cx,[edi-2]              ; cx = scan[0..1]
  101. short_loop:
  102.         dec     ebp                     ; --chain_length
  103.         jz      the_end
  104. ; at this point, edi == scan+2, esi == cur_match,
  105. ; ax = scan[best_len-1..best_len] and cx = scan[0..1]
  106.         and     esi,WSIZE-1
  107.         mov     si,_prev[esi+esi]       ; cur_match = prev[cur_match]
  108.                                         ; top word of esi is still 0
  109.         cmp     esi,edx                 ; cur_match <= limit ?
  110.         jbe     short the_end
  111. do_scan:
  112.         cmp     ax,word ptr _window[ebx+esi-1]   ; check match at best_len-1
  113.         jne     short_loop
  114.         cmp     cx,word ptr _window[esi]         ; check min_match_length match
  115.         jne     short_loop
  116.  
  117.         lea     esi,_window[esi+2]      ; si = match
  118.         mov     eax,edi                 ; ax = scan+2
  119.         mov     ecx,(MAX_MATCH-2)/2     ; scan for at most MAX_MATCH bytes
  120.         repe    cmpsw                   ; loop until mismatch
  121.         je      maxmatch                ; match of length MAX_MATCH?
  122. mismatch:
  123.         mov     cl,[edi-2]              ; mismatch on first or second byte?
  124.         sub     cl,[esi-2]              ; cl = 0 if first bytes equal
  125.         xchg    eax,edi                 ; edi = scan+2, eax = end of scan
  126.         sub     eax,edi                 ; eax = len
  127.         sub     esi,eax                 ; esi = cur_match + 2 + offset(window)
  128.         sub     esi,2+offset _window    ; esi = cur_match
  129.         sub     cl,1                    ; set carry if cl == 0 (can't use DEC)
  130.         adc     eax,0                   ; eax = carry ? len+1 : len
  131.         cmp     eax,ebx                 ; len > best_len ?
  132.         jle     long_loop
  133.         mov     _match_start,esi        ; match_start = cur_match
  134.         mov     ebx,eax                 ; ebx = best_len = len
  135.         cmp     eax,MAX_MATCH           ; len >= MAX_MATCH ?
  136.         jl      long_loop
  137. the_end:
  138.         mov     eax,ebx                 ; result = eax = best_len
  139.         pop     ebx
  140.         pop     esi
  141.         pop     edi
  142.         pop     ebp
  143.         ret
  144. maxmatch:                               ; come here if maximum match
  145.         cmpsb                           ; increment esi and edi
  146.         jmp     mismatch                ; force match_length = MAX_LENGTH
  147.  
  148. _longest_match endp
  149.  
  150. _TEXT   ends
  151. end
  152.