⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gvmat32.asm

📁 A new version of the StormLib library, supporting new version of MPQ archives (World of Warcraft and
💻 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  match_initELSE                        public  _longest_match_7fff;                        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        mov     match_start,eax     ; save new position as match_start        cmp     esi,nice_match      ; if best_len >= nice_match, exit        jae     exitloop        mov     ecx,scan        mov     edx,window          ; restore edx=window        add     ecx,esi        add     esi,edx        dec     esi        mov     windowlen,esi       ; windowlen = window + best_len-1        mov     bx,[ecx-1]          ; bx = *(scan+best_len-1) = scan_end; now we restore ecx and esi, for the big loop :        mov     esi,prev        mov     ecx,limit        jmp     contloop3exitloop:; exit : s->match_start=match_start        mov     ebx,match_start        mov     ebp,str_s        mov     ecx,best_len        mov     dword ptr [ebp+dep_match_start],ebx                mov     eax,dword ptr [ebp+dep_lookahead]        cmp     ecx,eax        ja      minexlo        mov     eax,ecxminexlo:; return min(best_len,s->lookahead)        ; restore stack and register ebx,esi,edi,ebp        add     esp,NbStackAdd        pop     ebx        pop     esi        pop     edi        pop     ebp        retInfoAuthor:; please don't remove this string !; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!        db     0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ahIFDEF NOUNDERLINElongest_match_7fff   endpELSE_longest_match_7fff  endpENDIFIFDEF NOUNDERLINEcpudetect32     proc nearELSE_cpudetect32    proc nearENDIF	pushfd                  ; push original EFLAGS	pop     eax             ; get original EFLAGS	mov     ecx, eax        ; save original EFLAGS	xor     eax, 40000h     ; flip AC bit in EFLAGS	push    eax             ; save new EFLAGS value on stack	popfd                   ; replace current EFLAGS value	pushfd                  ; get new EFLAGS	pop     eax             ; store new EFLAGS in EAX	xor     eax, ecx        ; can抰 toggle AC bit, processor=80386	jz      end_cpu_is_386  ; jump if 80386 processor	push    ecx	popfd                   ; restore AC bit in EFLAGS first	pushfd	pushfd	pop     ecx				mov     eax, ecx        ; get original EFLAGS	xor     eax, 200000h    ; flip ID bit in EFLAGS	push    eax             ; save new EFLAGS value on stack	popfd                   ; replace current EFLAGS value	pushfd                  ; get new EFLAGS	pop		eax	            ; store new EFLAGS in EAX	popfd                   ; restore original EFLAGS	xor		eax, ecx        ; can抰 toggle ID bit,	je		is_old_486		; processor=old	mov     eax,1	db      0fh,0a2h        ;CPUID   exitcpudetect:	retend_cpu_is_386:	mov     eax,0300h	jmp     exitcpudetectis_old_486:	mov     eax,0400h	jmp     exitcpudetectIFDEF NOUNDERLINEcpudetect32     endpELSE_cpudetect32    endpENDIF_TEXT   endsend

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -