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

📄 gvmat32y.asm

📁 cryptlib安全工具包
💻 ASM
📖 第 1 页 / 共 2 页
字号:

    and     edx,0ffffffh
    jnz     trfin
    inc     esi

trfin:
    sub     esi,scan          ; esi = len
trfinval:
; here we have finised compare, and esi contain len %define of al 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     contloop3

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 [ebp+dep_match_start],ebx
    mov     eax,dword [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
InfoAuthor:
; 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,0ah




%ifdef NOUNDERLINE
cpudetect32     proc near
%else
_cpudetect32    proc near
%endif

    push    ebx

    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:
    pop ebx
    ret

end_cpu_is_386:
    mov     eax,0300h
    jmp     exitcpudetect

is_old_486:
    mov     eax,0400h
    jmp     exitcpudetect

%endif

%define MAX_MATCH      258
%define MIN_MATCH      3
%define MIN_LOOKAHEAD      (MAX_MATCH + MIN_MATCH + 1)
%define MAX_MATCH_8_      ((MAX_MATCH + 7) AND 0FFF0h)


;;; stack frame offsets

%define chainlenwmask   esp + 0    ; high word: current chain len
                    ; low word: s->wmask
%define window   esp + 4    ; local copy of s->window
%define windowbestlen   esp + 8    ; s->window + bestlen
%define scanstart   esp + 16   ; first two bytes of string
%define scanend   esp + 12   ; last two bytes of string
%define scanalign   esp + 20   ; dword-misalignment of string
%define nicematch   esp + 24   ; a good enough match size
%define bestlen   esp + 28   ; size of best match so far
%define scan   esp + 32   ; ptr to string wanting match

%define LocalVarsSize  36
;   saved ebx   byte esp + 36
;   saved edi   byte esp + 40
;   saved esi   byte esp + 44
;   saved ebp   byte esp + 48
;   return address  byte esp + 52
%define deflatestate   esp + 56   ; the function arguments
%define curmatch   esp + 60

;;; Offsets for fields in the deflate_state structure. These numbers
;;; are calculated from the definition of deflate_state, with the
;;; assumption that the compiler will dword-align the fields. (Thus,
;;; changing the definition of deflate_state could easily cause this
;;; program to crash horribly, without so much as a warning at
;;; compile time. Sigh.)

%define dsWSize  36+zlib1222add
%define dsWMask  44+zlib1222add
%define dsWindow  48+zlib1222add
%define dsPrev  56+zlib1222add
%define dsMatchLen  88+zlib1222add
%define dsPrevMatch  92+zlib1222add
%define dsStrStart  100+zlib1222add
%define dsMatchStart  104+zlib1222add
%define dsLookahead  108+zlib1222add
%define dsPrevLen  112+zlib1222add
%define dsMaxChainLen  116+zlib1222add
%define dsGoodMatch  132+zlib1222add
%define dsNiceMatch  136+zlib1222add


;;; match.asm -- Pentium-Pro-optimized version of longest_match()
;;; Written for zlib 1.1.2
;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
;;;
;;; This is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General global License.

;GLOBAL _longest_match, _match_init


;SECTION    .text

;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)

;_longest_match:
%ifdef NOOLDPENTIUMCODE
    %ifdef NOUNDERLINE
    longest_match       proc near
    %else
    _longest_match      proc near
    %endif
%else
    %ifdef NOUNDERLINE
    longest_match_686   proc near
    %else
    _longest_match_686  proc near
    %endif
%endif

;;; Save registers that the compiler may be using, and adjust esp to
;;; make room for our stack frame.

        push    ebp
        push    edi
        push    esi
        push    ebx
        sub esp, LocalVarsSize

;;; Retrieve the function arguments. ecx will hold cur_match
;;; throughout the entire function. edx will hold the pointer to the
;;; deflate_state structure during the function's setup (before
;;; entering the main loop.

        mov edx, [deflatestate]
        mov ecx, [curmatch]

;;; uInt wmask = s->w_mask;
;;; unsigned chain_length = s->max_chain_length;
;;; if (s->prev_length >= s->good_match) {
;;;     chain_length >>= 2;
;;; }

        mov eax, [edx + dsPrevLen]
        mov ebx, [edx + dsGoodMatch]
        cmp eax, ebx
        mov eax, [edx + dsWMask]
        mov ebx, [edx + dsMaxChainLen]
        jl  LastMatchGood
        shr ebx, 2
LastMatchGood:

;;; chainlen is decremented once beforehand so that the function can
;;; use the sign flag instead of the zero flag for the exit test.
;;; It is then shifted into the high word, to make room for the wmask
;;; value, which it will always accompany.

        dec ebx
        shl ebx, 16
        or  ebx, eax
        mov [chainlenwmask], ebx

;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;

        mov eax, [edx + dsNiceMatch]
        mov ebx, [edx + dsLookahead]
        cmp ebx, eax
        jl  LookaheadLess
        mov ebx, eax
LookaheadLess:  mov [nicematch], ebx

;;; register Bytef *scan = s->window + s->strstart;

        mov esi, [edx + dsWindow]
        mov [window], esi
        mov ebp, [edx + dsStrStart]
        lea edi, [esi + ebp]
        mov [scan], edi

;;; Determine how many bytes the scan ptr is off from being
;;; dword-aligned.

        mov eax, edi
        neg eax
        and eax, 3
        mov [scanalign], eax

;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;

        mov eax, [edx + dsWSize]
        sub eax, MIN_LOOKAHEAD
        sub ebp, eax
        jg  LimitPositive
        xor ebp, ebp
LimitPositive:

;;; int best_len = s->prev_length;

        mov eax, [edx + dsPrevLen]
        mov [bestlen], eax

;;; Store the sum of s->window + best_len in esi locally, and in esi.

        add esi, eax
        mov [windowbestlen], esi

;;; register ush scan_start = *(ushf*)scan;
;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
;;; Posf *prev = s->prev;

        movzx   ebx, word [edi]
        mov [scanstart], ebx
        movzx   ebx, word [edi + eax - 1]
        mov [scanend], ebx
        mov edi, [edx + dsPrev]

;;; Jump into the main loop.

        mov edx, [chainlenwmask]
        jmp short LoopEntry

align 4

;;; do {
;;;     match = s->window + cur_match;
;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
;;;         *(ushf*)match != scan_start) continue;
;;;     [...]
;;; } while ((cur_match = prev[cur_match & wmask]) > limit
;;;          && --chain_length != 0);
;;;
;;; Here is the inner loop of the function. The function will spend the
;;; majority of its time in this loop, and majority of that time will
;;; be spent in the first ten instructions.
;;;
;;; Within this loop:
;;; ebx = scanend
;;; ecx = curmatch
;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
;;; esi = windowbestlen - i.e., (window + bestlen)
;;; edi = prev
;;; ebp = limit

LookupLoop:
        and ecx, edx
        movzx   ecx, word [edi + ecx*2]
        cmp ecx, ebp
        jbe LeaveNow
        sub edx, 00010000h
        js  LeaveNow
LoopEntry:  movzx   eax, word [esi + ecx - 1]
        cmp eax, ebx
        jnz LookupLoop
        mov eax, [window]
        movzx   eax, word [eax + ecx]
        cmp eax, [scanstart]
        jnz LookupLoop

;;; Store the current value of chainlen.

        mov [chainlenwmask], edx

;;; Point edi to the string under scrutiny, and esi to the string we
;;; are hoping to match it up with. In actuality, esi and edi are
;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
;;; initialized to -(MAX_MATCH_8 - scanalign).

        mov esi, [window]
        mov edi, [scan]
        add esi, ecx
        mov eax, [scanalign]
        mov edx, 0fffffef8h; -(MAX_MATCH_8)
        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]

;;; Test the strings %define for ality, 8 bytes at a time. At the end,
;;; adjust edx so that it is offset to the exact byte that mismatched.
;;;
;;; We already know at this point that the first three bytes of the
;;; strings match each other, and they can be safely passed over before
;;; starting the compare loop. So what this code does is skip over 0-3
;;; bytes, as much as necessary in order to dword-align the edi
;;; pointer. (esi will still be misaligned three times out of four.)
;;;
;;; It should be confessed that this loop usually does not represent
;;; much of the total running time. Replacing it with a more
;;; straightforward "rep cmpsb" would not drastically degrade
;;; performance.

LoopCmps:
        mov eax, [esi + edx]
        xor eax, [edi + edx]
        jnz LeaveLoopCmps
        mov eax, [esi + edx + 4]
        xor eax, [edi + edx + 4]
        jnz LeaveLoopCmps4
        add edx, 8
        jnz LoopCmps
        jmp short LenMaximum
LeaveLoopCmps4: add edx, 4
LeaveLoopCmps:  test    eax, 0000FFFFh
        jnz LenLower
        add edx,  2
        shr eax, 16
LenLower:   sub al, 1
        adc edx, 0

;;; Calculate the length of the match. If it is longer than MAX_MATCH,
;;; then automatically accept it as the best possible match and leave.

        lea eax, [edi + edx]
        mov edi, [scan]
        sub eax, edi
        cmp eax, MAX_MATCH
        jge LenMaximum

;;; If the length of the match is not longer than the best match we
;;; have so far, then forget it and return to the lookup loop.

        mov edx, [deflatestate]
        mov ebx, [bestlen]
        cmp eax, ebx
        jg  LongerMatch
        mov esi, [windowbestlen]
        mov edi, [edx + dsPrev]
        mov ebx, [scanend]
        mov edx, [chainlenwmask]
        jmp LookupLoop

;;;         s->match_start = cur_match;
;;;         best_len = len;
;;;         if (len >= nice_match) break;
;;;         scan_end = *(ushf*)(scan+best_len-1);

LongerMatch:    mov ebx, [nicematch]
        mov [bestlen], eax
        mov [edx + dsMatchStart], ecx
        cmp eax, ebx
        jge LeaveNow
        mov esi, [window]
        add esi, eax
        mov [windowbestlen], esi
        movzx   ebx, word [edi + eax - 1]
        mov edi, [edx + dsPrev]
        mov [scanend], ebx
        mov edx, [chainlenwmask]
        jmp LookupLoop

;;; Accept the current string, with the maximum possible length.

LenMaximum: mov edx, [deflatestate]
        mov dword [bestlen], MAX_MATCH
        mov [edx + dsMatchStart], ecx

;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
;;; return s->lookahead;

LeaveNow:
        mov edx, [deflatestate]
        mov ebx, [bestlen]
        mov eax, [edx + dsLookahead]
        cmp ebx, eax
        jg  LookaheadRet
        mov eax, ebx
LookaheadRet:

;;; Restore the stack and return from whence we came.

        add esp, LocalVarsSize
        pop ebx
        pop esi
        pop edi
        pop ebp

        ret
; please don't remove this string !
; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah


%ifdef NOOLDPENTIUMCODE

    %ifdef NOUNDERLINE
	    match_init:	ret
    %else
		_match_init: ret
    %endif    
    %ifdef DLL
    %ifdef NOUNDERLINE
	    export	match_init
    %else
		export	_match_init
    %endif        
    %endif
%endif

	end

⌨️ 快捷键说明

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