?? gvmat32.asm
字號:
;; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.; File written by Gilles Vollant, by modifiying the longest_match; from Jean-loup Gailly in deflate.c; It need wmask == 0x7fff; (assembly code is faster with a fixed wmask);; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK); I compile with : "ml /coff /Zi /c gvmat32.asm";;uInt longest_match_7fff(s, cur_match); deflate_state *s;; IPos cur_match; /* current match */ NbStack equ 76 cur_match equ dword ptr[esp+NbStack-0] str_s equ dword ptr[esp+NbStack-4]; 5 dword on top (ret,ebp,esi,edi,ebx) adrret equ dword ptr[esp+NbStack-8] pushebp equ dword ptr[esp+NbStack-12] pushedi equ dword ptr[esp+NbStack-16] pushesi equ dword ptr[esp+NbStack-20] pushebx equ dword ptr[esp+NbStack-24] chain_length equ dword ptr [esp+NbStack-28] limit equ dword ptr [esp+NbStack-32] best_len equ dword ptr [esp+NbStack-36] window equ dword ptr [esp+NbStack-40] prev equ dword ptr [esp+NbStack-44] scan_start equ word ptr [esp+NbStack-48] wmask equ dword ptr [esp+NbStack-52] match_start_ptr equ dword ptr [esp+NbStack-56] nice_match equ dword ptr [esp+NbStack-60] scan equ dword ptr [esp+NbStack-64] windowlen equ dword ptr [esp+NbStack-68] match_start equ dword ptr [esp+NbStack-72] strend equ dword ptr [esp+NbStack-76] NbStackAdd equ (NbStack-24) .386p name gvmatch .MODEL FLAT; all the +4 offsets are due to the addition of pending_buf_size (in zlib; in the deflate_state structure since the asm code was first written; (if you compile with zlib 1.0.4 or older, remove the +4).; Note : these value are good with a 8 bytes boundary pack structure dep_chain_length equ 70h+4 dep_window equ 2ch+4 dep_strstart equ 60h+4 dep_prev_length equ 6ch+4 dep_nice_match equ 84h+4 dep_w_size equ 20h+4 dep_prev equ 34h+4 dep_w_mask equ 28h+4 dep_good_match equ 80h+4 dep_match_start equ 64h+4 dep_lookahead equ 68h+4_TEXT segmentIFDEF NOUNDERLINE public longest_match_7fff public longest_match_686; public match_initELSE public _longest_match_7fff public _longest_match_686; public _match_initENDIF MAX_MATCH equ 258 MIN_MATCH equ 3 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)IFDEF NOUNDERLINE;match_init proc near; ret;match_init endpELSE;_match_init proc near; ret;_match_init endpENDIFIFDEF NOUNDERLINElongest_match_7fff proc nearELSE_longest_match_7fff proc nearENDIF mov edx,[esp+4] push ebp push edi push esi push ebx sub esp,NbStackAdd; initialize or check the variables used in match.asm. mov ebp,edx; chain_length = s->max_chain_length; if (prev_length>=good_match) chain_length >>= 2 mov edx,[ebp+dep_chain_length] mov ebx,[ebp+dep_prev_length] cmp [ebp+dep_good_match],ebx ja noshr shr edx,2noshr:; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop inc edx mov edi,[ebp+dep_nice_match] mov chain_length,edx mov eax,[ebp+dep_lookahead] cmp eax,edi; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; jae nolookaheadnicematch mov edi,eaxnolookaheadnicematch:; best_len = s->prev_length mov best_len,ebx; window = s->window mov esi,[ebp+dep_window] mov ecx,[ebp+dep_strstart] mov window,esi mov nice_match,edi; scan = window + strstart add esi,ecx mov scan,esi; dx = *window mov dx,word ptr [esi]; bx = *(window+best_len-1) mov bx,word ptr [esi+ebx-1] add esi,MAX_MATCH-1; scan_start = *scan mov scan_start,dx; strend = scan + MAX_MATCH-1 mov strend,esi; bx = scan_end = *(window+best_len-1); IPos limit = s->strstart > (IPos)MAX_DIST(s) ?; s->strstart - (IPos)MAX_DIST(s) : NIL; mov esi,[ebp+dep_w_size] sub esi,MIN_LOOKAHEAD; here esi = MAX_DIST(s) sub ecx,esi ja nodist xor ecx,ecxnodist: mov limit,ecx; prev = s->prev mov edx,[ebp+dep_prev] mov prev,edx; mov edx,dword ptr [ebp+dep_match_start] mov bp,scan_start mov eax,cur_match mov match_start,edx mov edx,window mov edi,edx add edi,best_len mov esi,prev dec edi; windowlen = window + best_len -1 mov windowlen,edi jmp beginloop2 align 4; here, in the loop; eax = ax = cur_match; ecx = limit; bx = scan_end; bp = scan_start; edi = windowlen (window + best_len -1); esi = prev;// here; chain_length <=16normalbeg0add16: add chain_length,16 jz exitloopnormalbeg0: cmp word ptr[edi+eax],bx je normalbeg2norollrcontlabnoroll:; cur_match = prev[cur_match & wmask] and eax,7fffh mov ax,word ptr[esi+eax*2]; if cur_match > limit, go to exitloop cmp ecx,eax jnb exitloop; if --chain_length != 0, go to exitloop dec chain_length jnz normalbeg0 jmp exitloopnormalbeg2noroll:; if (scan_start==*(cur_match+window)) goto normalbeg2 cmp bp,word ptr[edx+eax] jne rcontlabnoroll jmp normalbeg2contloop3: mov edi,windowlen; cur_match = prev[cur_match & wmask] and eax,7fffh mov ax,word ptr[esi+eax*2]; if cur_match > limit, go to exitloop cmp ecx,eaxjnbexitloopshort1: jnb exitloop; if --chain_length != 0, go to exitloop; begin the main loopbeginloop2: sub chain_length,16+1; if chain_length <=16, don't use the unrolled loop jna normalbeg0add16do16: cmp word ptr[edi+eax],bx je normalbeg2dc0maccn MACRO lab and eax,7fffh mov ax,word ptr[esi+eax*2] cmp ecx,eax jnb exitloop cmp word ptr[edi+eax],bx je lab ENDMrcontloop0: maccn normalbeg2dc1rcontloop1: maccn normalbeg2dc2rcontloop2: maccn normalbeg2dc3rcontloop3: maccn normalbeg2dc4rcontloop4: maccn normalbeg2dc5rcontloop5: maccn normalbeg2dc6rcontloop6: maccn normalbeg2dc7rcontloop7: maccn normalbeg2dc8rcontloop8: maccn normalbeg2dc9rcontloop9: maccn normalbeg2dc10rcontloop10: maccn short normalbeg2dc11rcontloop11: maccn short normalbeg2dc12rcontloop12: maccn short normalbeg2dc13rcontloop13: maccn short normalbeg2dc14rcontloop14: maccn short normalbeg2dc15rcontloop15: and eax,7fffh mov ax,word ptr[esi+eax*2] cmp ecx,eax jnb exitloop sub chain_length,16 ja do16 jmp normalbeg0add16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;normbeg MACRO rcontlab,valsub; if we are here, we know that *(match+best_len-1) == scan_end cmp bp,word ptr[edx+eax]; if (match != scan_start) goto rcontlab jne rcontlab; calculate the good chain_length, and we'll compare scan and match string add chain_length,16-valsub jmp iseq ENDMnormalbeg2dc11: normbeg rcontloop11,11normalbeg2dc12: normbeg short rcontloop12,12normalbeg2dc13: normbeg short rcontloop13,13normalbeg2dc14: normbeg short rcontloop14,14normalbeg2dc15: normbeg short rcontloop15,15normalbeg2dc10: normbeg rcontloop10,10normalbeg2dc9: normbeg rcontloop9,9normalbeg2dc8: normbeg rcontloop8,8normalbeg2dc7: normbeg rcontloop7,7normalbeg2dc6: normbeg rcontloop6,6normalbeg2dc5: normbeg rcontloop5,5normalbeg2dc4: normbeg rcontloop4,4normalbeg2dc3: normbeg rcontloop3,3normalbeg2dc2: normbeg rcontloop2,2normalbeg2dc1: normbeg rcontloop1,1normalbeg2dc0: normbeg rcontloop0,0; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_endnormalbeg2: mov edi,window cmp bp,word ptr[edi+eax] jne contloop3 ; if *(ushf*)match != scan_start, continueiseq:; if we are here, we know that *(match+best_len-1) == scan_end; and (match == scan_start) mov edi,edx mov esi,scan ; esi = scan add edi,eax ; edi = window + cur_match = match mov edx,[esi+3] ; compare manually dword at match+3 xor edx,[edi+3] ; and scan +3 jz begincompare ; if equal, go to long compare; we will determine the unmatch byte and calculate len (in esi) or dl,dl je eq1rr mov esi,3 jmp trfinvaleq1rr: or dx,dx je eq1 mov esi,4 jmp trfinvaleq1: and edx,0ffffffh jz eq11 mov esi,5 jmp trfinvaleq11: mov esi,6 jmp trfinvalbegincompare: ; here we now scan and match begin same add edi,6 add esi,6 mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes repe cmpsd ; loop until mismatch je trfin ; go to trfin if not unmatch; we determine the unmatch byte sub esi,4 mov edx,[edi-4] xor edx,[esi] or dl,dl jnz trfin inc esi or dx,dx jnz trfin inc esi and edx,0ffffffh jnz trfin inc esitrfin: sub esi,scan ; esi = lentrfinval:; here we have finised compare, and esi contain len of equal string cmp esi,best_len ; if len > best_len, go newbestlen ja short newbestlen; now we restore edx, ecx and esi, for the big loop mov esi,prev mov ecx,limit mov edx,window jmp contloop3newbestlen: mov best_len,esi ; len become best_len
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -