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

📄 gvmat32.asm

📁 ocx 代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
newbestlen:
        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     contloop3

exitloop:
; 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,ecx
minexlo:
; 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
        ret



; now : the generic version
; (mask is not fixed)

longest_match_generic:
        push    ebp
        push    edi
        push    esi
        push    ebx

        sub     esp,NbStackAdd

; initialize or check the variables used in match.asm.

        and     eax,0ffffh 
        mov     ebp,edx

        mov     wmask,eax

; 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      gnoshr
        shr     edx,2
gnoshr:
; 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     gnolookaheadnicematch
        mov     edi,eax
gnolookaheadnicematch:
; 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      gnodist
        xor     ecx,ecx
gnodist:
        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     gbeginloop2
        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 <=16
gnormalbeg0add16:
        add     chain_length,16
        jz      gexitloop
gnormalbeg0:
        cmp     word ptr[edi+eax],bx
        je      gnormalbeg2noroll
grcontlabnoroll:
; cur_match = prev[cur_match & wmask]
        and     eax,wmask
        mov     ax,word ptr[esi+eax*2]
; if cur_match > limit, go to exitloop
        cmp     ecx,eax
        jnb     gexitloop
; if --chain_length != 0, go to exitloop
        dec     chain_length
        jnz     gnormalbeg0
        jmp     gexitloop

gnormalbeg2noroll:
; if (scan_start==*(cur_match+window)) goto normalbeg2
        cmp     bp,word ptr[edx+eax]
        jne     grcontlabnoroll
        jmp     gnormalbeg2

gcontloop3:
        mov     edi,windowlen

; cur_match = prev[cur_match & wmask]
        and     eax,wmask
        mov     ax,word ptr[esi+eax*2]
; if cur_match > limit, go to exitloop
        cmp     ecx,eax
gjnbexitloopshort1:
        jnb     gexitloop
; if --chain_length != 0, go to exitloop


; begin the main loop
gbeginloop2:
        sub     chain_length,16+1
; if chain_length <=16, don't use the unrolled loop
        jna     gnormalbeg0add16

gdo16:
        cmp     word ptr[edi+eax],bx
        je      gnormalbeg2dc0

gmaccn  MACRO   glab
        and     eax,wmask
        mov     ax,word ptr[esi+eax*2]
        cmp     ecx,eax
        jnb     gexitloop
        cmp     word ptr[edi+eax],bx
        je      glab
        ENDM

grcontloop0:
        gmaccn  gnormalbeg2dc1

grcontloop1:
        gmaccn  gnormalbeg2dc2

grcontloop2:
        gmaccn  gnormalbeg2dc3

grcontloop3:
        gmaccn  gnormalbeg2dc4

grcontloop4:
        gmaccn  gnormalbeg2dc5

grcontloop5:
        gmaccn  gnormalbeg2dc6

grcontloop6:
        gmaccn  gnormalbeg2dc7

grcontloop7:
        gmaccn  gnormalbeg2dc8

grcontloop8:
        gmaccn  gnormalbeg2dc9

grcontloop9:
        gmaccn  gnormalbeg2dc10

grcontloop10:
        gmaccn  short gnormalbeg2dc11

grcontloop11:
        gmaccn  short gnormalbeg2dc12

grcontloop12:
        gmaccn  short gnormalbeg2dc13

grcontloop13:
        gmaccn  short gnormalbeg2dc14

grcontloop14:
        gmaccn  short gnormalbeg2dc15

grcontloop15:
        and     eax,wmask
        mov     ax,word ptr[esi+eax*2]
        cmp     ecx,eax
        jnb     gexitloop

        sub     chain_length,16
        ja      gdo16
        jmp     gnormalbeg0add16

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

gnormbeg MACRO   grcontlab,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     grcontlab
; calculate the good chain_length, and we'll compare scan and match string
        add     chain_length,16-valsub
        jmp     giseq
        ENDM



gnormalbeg2dc11:
        gnormbeg grcontloop11,11

gnormalbeg2dc12:
        gnormbeg short grcontloop12,12

gnormalbeg2dc13:
        gnormbeg short grcontloop13,13

gnormalbeg2dc14:
        gnormbeg short grcontloop14,14

gnormalbeg2dc15:
        gnormbeg short grcontloop15,15

gnormalbeg2dc10:
        gnormbeg grcontloop10,10

gnormalbeg2dc9:
        gnormbeg grcontloop9,9

gnormalbeg2dc8:
        gnormbeg grcontloop8,8

gnormalbeg2dc7:
        gnormbeg grcontloop7,7

gnormalbeg2dc6:
        gnormbeg grcontloop6,6

gnormalbeg2dc5:
        gnormbeg grcontloop5,5

gnormalbeg2dc4:
        gnormbeg grcontloop4,4

gnormalbeg2dc3:
        gnormbeg grcontloop3,3

gnormalbeg2dc2:
        gnormbeg grcontloop2,2

gnormalbeg2dc1:
        gnormbeg grcontloop1,1

gnormalbeg2dc0:
        gnormbeg grcontloop0,0


; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end

gnormalbeg2:
        mov     edi,window

        cmp     bp,word ptr[edi+eax]
        jne     gcontloop3                   ; if *(ushf*)match != scan_start, continue

giseq:
; 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      gbegincompare                ; if equal, go to long compare

; we will determine the unmatch byte and calculate len (in esi)
        or      dl,dl
        je      geq1rr
        mov     esi,3
        jmp     gtrfinval
geq1rr:
        or      dx,dx
        je      geq1

        mov     esi,4
        jmp     gtrfinval
geq1:
        and     edx,0ffffffh
        jz      geq11
        mov     esi,5
        jmp     gtrfinval
geq11:
        mov     esi,6
        jmp     gtrfinval

gbegincompare:
        ; 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      gtrfin                       ; 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     gtrfin
        inc     esi

        or      dx,dx
        jnz     gtrfin
        inc     esi

        and     edx,0ffffffh
        jnz     gtrfin
        inc     esi

gtrfin:
        sub     esi,scan          ; esi = len
gtrfinval:
; here we have finised compare, and esi contain len of equal string
        cmp     esi,best_len        ; if len > best_len, go newbestlen
        ja      short gnewbestlen
; now we restore edx, ecx and esi, for the big loop
        mov     esi,prev
        mov     ecx,limit
        mov     edx,window
        jmp     gcontloop3

gnewbestlen:
        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     gexitloop
        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     gcontloop3

gexitloop:
; 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      gminexlo
        mov     eax,ecx
gminexlo:
; 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
        ret


IFDEF NOUNDERLINE
longest_match   endp
ELSE
_longest_match  endp
ENDIF

_TEXT   ends
end

⌨️ 快捷键说明

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