match32.asm 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. ;===========================================================================
  2. ; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
  3. ;
  4. ; See the accompanying file LICENSE, version 2005-Feb-10 or later
  5. ; (the contents of which are also included in zip.h) for terms of use.
  6. ; If, for some reason, all these files are missing, the Info-ZIP license
  7. ; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  8. ;===========================================================================
  9. ;
  10. ; match32.asm by Jean-loup Gailly.
  11. ; match32.asm, optimized version of longest_match() in deflate.c
  12. ; To be used only with 32 bit flat model. To simplify the code, the option
  13. ; -DDYN_ALLOC is not supported.
  14. ; This file is only optional. If you don't have an assembler, use the
  15. ; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o
  16. ; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
  17. ; assembled with an equivalent -DWSIZE=<whatever>.
  18. ;
  19. ; Win32 (Windows NT) version - 1994/04/13 by Steve Salisbury
  20. ; * works with Microsoft MASM 6.1X and Microsoft Visual C++ / 32-bit edition
  21. ;
  22. ; Adapted to work with Borland Turbo Assembler 5.0 by Cosmin Truta, 1997
  23. ;
  24. ; Adapted to work with OpenWatcom WASM by Chr. Spieler, 2005
  25. ; (Define the symbol WATCOM_DSEG to activate the specific Watcom C
  26. ; data segment naming convention.)
  27. ;
  28. ;==============================================================================
  29. ;
  30. ; Do NOT assemble this source if external crc32 routine from zlib gets used.
  31. ;
  32. IFNDEF USE_ZLIB
  33. ;
  34. .386p
  35. ifdef ASM_NEW
  36. .MODEL FLAT
  37. endif
  38. name match
  39. ifdef ASM_NEW
  40. _BSS segment public use32
  41. else
  42. _BSS segment public use32 'DATA'
  43. endif
  44. extrn _match_start : dword
  45. extrn _prev_length : dword
  46. extrn _good_match : dword
  47. ifndef FULL_SEARCH
  48. extrn _nice_match : dword
  49. endif
  50. extrn _strstart : dword
  51. extrn _max_chain_length : dword
  52. extrn _prev : word
  53. extrn _window : byte
  54. _BSS ends
  55. ifdef WATCOM_DSEG
  56. DGROUP group _BSS
  57. endif
  58. ifdef ASM_NEW
  59. _TEXT segment public use32
  60. else
  61. _TEXT segment para public use32 'CODE'
  62. endif
  63. assume CS: _TEXT
  64. assume DS: _BSS, ES: _BSS, FS: _BSS
  65. public _match_init
  66. public _longest_match
  67. ifndef WSIZE
  68. WSIZE equ 32768 ; keep in sync with zip.h !
  69. endif
  70. MIN_MATCH equ 3
  71. MAX_MATCH equ 258
  72. MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
  73. MAX_DIST equ (WSIZE-MIN_LOOKAHEAD)
  74. ; initialize or check the variables used in match.asm.
  75. _match_init proc near
  76. ret
  77. _match_init endp
  78. ; -----------------------------------------------------------------------
  79. ; Set match_start to the longest match starting at the given string and
  80. ; return its length. Matches shorter or equal to prev_length are discarded,
  81. ; in which case the result is equal to prev_length and match_start is
  82. ; garbage.
  83. ; IN assertions: cur_match is the head of the hash chain for the current
  84. ; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  85. ; int longest_match(cur_match)
  86. _longest_match proc near
  87. cur_match equ dword ptr [esp+20]
  88. ; return address ; esp+16
  89. push ebp ; esp+12
  90. push edi ; esp+8
  91. push esi ; esp+4
  92. push ebx ; esp
  93. ; match equ esi
  94. ; scan equ edi
  95. ; chain_length equ ebp
  96. ; best_len equ ebx
  97. ; limit equ edx
  98. mov esi,cur_match
  99. mov edx,_strstart
  100. mov ebp,_max_chain_length ; chain_length = max_chain_length
  101. mov edi,edx
  102. sub edx,MAX_DIST ; limit = strstart-MAX_DIST
  103. cld ; string ops increment esi and edi
  104. jae short limit_ok
  105. sub edx,edx ; limit = NIL
  106. limit_ok:
  107. add edi,2+offset _window ; edi = offset(window + strstart + 2)
  108. mov ebx,_prev_length ; best_len = prev_length
  109. mov cx,[edi-2] ; cx = scan[0..1]
  110. mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len]
  111. cmp ebx,_good_match ; do we have a good match already?
  112. jb short do_scan
  113. shr ebp,2 ; chain_length >>= 2
  114. jmp short do_scan
  115. align 4 ; align destination of branch
  116. long_loop:
  117. ; at this point, edi == scan+2, esi == cur_match
  118. mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len]
  119. mov cx,[edi-2] ; cx = scan[0..1]
  120. short_loop:
  121. ; at this point, edi == scan+2, esi == cur_match,
  122. ; ax = scan[best_len-1..best_len] and cx = scan[0..1]
  123. and esi,WSIZE-1
  124. dec ebp ; --chain_length
  125. mov si,_prev[esi+esi] ; cur_match = prev[cur_match]
  126. ; top word of esi is still 0
  127. jz short the_end
  128. cmp esi,edx ; cur_match <= limit ?
  129. jbe short the_end
  130. do_scan:
  131. cmp ax,word ptr _window[ebx+esi-1] ; check match at best_len-1
  132. jne short_loop
  133. cmp cx,word ptr _window[esi] ; check min_match_length match
  134. jne short_loop
  135. lea esi,_window[esi+2] ; esi = match
  136. mov ecx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes
  137. mov eax,edi ; eax = scan+2
  138. repe cmpsw ; loop until mismatch
  139. je short maxmatch ; match of length MAX_MATCH?
  140. mismatch:
  141. mov cl,[edi-2] ; mismatch on first or second byte?
  142. xchg eax,edi ; edi = scan+2, eax = end of scan
  143. sub cl,[esi-2] ; cl = 0 if first bytes equal
  144. sub eax,edi ; eax = len
  145. sub esi,2+offset _window ; esi = match - (2 + offset(window))
  146. sub esi,eax ; esi = cur_match (= match - len)
  147. sub cl,1 ; set carry if cl == 0 (can't use DEC)
  148. adc eax,0 ; eax = carry ? len+1 : len
  149. cmp eax,ebx ; len > best_len ?
  150. jle long_loop
  151. mov _match_start,esi ; match_start = cur_match
  152. mov ebx,eax ; ebx = best_len = len
  153. ifdef FULL_SEARCH
  154. cmp eax,MAX_MATCH ; len >= MAX_MATCH ?
  155. else
  156. cmp eax,_nice_match ; len >= nice_match ?
  157. endif
  158. jl long_loop
  159. the_end:
  160. mov eax,ebx ; result = eax = best_len
  161. pop ebx
  162. pop esi
  163. pop edi
  164. pop ebp
  165. ret
  166. maxmatch: ; come here if maximum match
  167. cmpsb ; increment esi and edi
  168. jmp mismatch ; force match_length = MAX_LENGTH
  169. _longest_match endp
  170. _TEXT ends
  171. ;
  172. ENDIF ; !USE_ZLIB
  173. ;
  174. end