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

📄 crc_i386.asm

📁 给出了 zip 压缩算法的完整实现过程。
💻 ASM
字号:
;===========================================================================; Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.;; See the accompanying file LICENSE, version 2004-May-22 or later; (the contents of which are also included in zip.h) for terms of use.; If, for some reason, all these files are missing, the Info-ZIP license; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html;===========================================================================; crc_i386.asm, optimized CRC calculation function for Zip and UnZip,; created by Paul Kienitz and Christian Spieler.;; Revised 06-Oct-96, Scott Field (sfield@microsoft.com);   fixed to assemble with masm by not using .model directive which makes;   assumptions about segment alignment.  Also,;   avoid using loop, and j[e]cxz where possible.  Use mov + inc, rather;   than lodsb, and other misc. changes resulting in the following performance;   increases:;;      unrolled loops                NO_UNROLLED_LOOPS;      *8    >8      <8              *8      >8      <8;;      +54%  +42%    +35%            +82%    +52%    +25%;;   first item in each table is input buffer length, even multiple of 8;   second item in each table is input buffer length, > 8;   third item in each table is input buffer length, < 8;; Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au);   Incorporated Rodney Brown's 32-bit-reads optimization as found in the;   UNIX AS source crc_i386.S. This new code can be disabled by defining;   the macro symbol NO_32_BIT_LOADS.;; Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au);   Incorporated Rodney Brown's additional tweaks for 32-bit-optimized CPUs;   (like the Pentium Pro, Pentium II, and probably some Pentium clones).;   This optimization is controlled by the macro symbol __686 and is disabled;   by default. (This default is based on the assumption that most users;   do not yet work on a Pentium Pro or Pentium II machine ...);; Revised 25-Mar-98, Cosmin Truta (cosmint@cs.ubbcluj.ro);   Working without .model directive caused tasm32 version 5.0 to produce;   bad object code. The optimized alignments can be optionally disabled;   by defining NO_ALIGN, thus allowing to use .model flat. There is no need;   to define this macro if using other versions of tasm.;; Revised 16-Jan-2005, Cosmin Truta (cosmint@cs.ubbcluj.ro);   Enabled the 686 build by default, because there are hardly any pre-686 CPUs;   in serious use nowadays. (See the 12-Oct-97 note above.);; FLAT memory model assumed.;; Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.; This results in shorter code at the expense of reduced performance.;;==============================================================================;; Do NOT assemble this source if external crc32 routine from zlib gets used.;    IFNDEF USE_ZLIB;        .386p        name    crc_i386    IFDEF NO_ALIGN        .model flat    ENDIF    IFNDEF PRE_686    IFNDEF __686__686   EQU     1 ; optimize for Pentium Pro, Pentium II and compatible CPUs    ENDIF    ENDIFextrn   _get_crc_table:near    ; ZCONST ulg near *get_crc_table(void);;    IFNDEF NO_STD_STACKFRAME        ; Use a `standard' stack frame setup on routine entry and exit.        ; Actually, this option is set as default, because it results        ; in smaller code !!STD_ENTRY       MACRO                push    ebp                mov     ebp,esp        ENDM        Arg1    EQU     08H[ebp]        Arg2    EQU     0CH[ebp]        Arg3    EQU     10H[ebp]STD_LEAVE       MACRO                pop     ebp        ENDM    ELSE  ; NO_STD_STACKFRAMESTD_ENTRY       MACRO        ENDM        Arg1    EQU     18H[esp]        Arg2    EQU     1CH[esp]        Arg3    EQU     20H[esp]STD_LEAVE       MACRO        ENDM    ENDIF ; ?NO_STD_STACKFRAME; These two (three) macros make up the loop body of the CRC32 cruncher.; registers modified:;   eax  : crc value "c";   esi  : pointer to next data byte (or dword) "buf++"; registers read:;   edi  : pointer to base of crc_table array; scratch registers:;   ebx  : index into crc_table array;          (requires upper three bytes = 0 when __686 is undefined)    IFNDEF  __686 ; optimize for 386, 486, PentiumDo_CRC  MACRO                mov     bl,al                ; tmp = c & 0xFF                shr     eax,8                ; c = (c >> 8)                xor     eax,[edi+ebx*4]      ;  ^ table[tmp]        ENDM    ELSE ; __686 : optimize for Pentium Pro, Pentium II and compatible CPUsDo_CRC  MACRO                movzx   ebx,al               ; tmp = c & 0xFF                shr     eax,8                ; c = (c >> 8)                xor     eax,[edi+ebx*4]      ;  ^ table[tmp]        ENDM    ENDIF ; ?__686Do_CRC_byte     MACRO                xor     al, byte ptr [esi]   ; c ^= *buf                inc     esi                  ; buf++                Do_CRC                       ; c = (c >> 8) ^ table[c & 0xFF]        ENDM    IFNDEF  NO_32_BIT_LOADSDo_CRC_dword    MACRO                xor     eax, dword ptr [esi] ; c ^= *(ulg *)buf                add     esi, 4               ; ((ulg *)buf)++                Do_CRC                Do_CRC                Do_CRC                Do_CRC        ENDM    ENDIF ; !NO_32_BIT_LOADS    IFNDEF NO_ALIGN_TEXT   segment use32 para public 'CODE'    ELSE_TEXT   segment use32    ENDIF        assume  CS: _TEXT        public  _crc32_crc32          proc    near  ; ulg crc32(ulg crc, ZCONST uch *buf, extent len)                STD_ENTRY                push    edi                push    esi                push    ebx                push    edx                push    ecx                mov     esi,Arg2             ; 2nd arg: uch *buf                sub     eax,eax              ;> if (!buf)                test    esi,esi              ;>   return 0;                jz      fine                 ;> else {                call    _get_crc_table                mov     edi,eax                mov     eax,Arg1             ; 1st arg: ulg crc    IFNDEF __686                sub     ebx,ebx              ; ebx=0; make bl usable as a dword    ENDIF                mov     ecx,Arg3             ; 3rd arg: extent len                not     eax                  ;>   c = ~crc;                test    ecx,ecx    IFNDEF  NO_UNROLLED_LOOPS                jz      bail    IFNDEF  NO_32_BIT_LOADSalign_loop:                test    esi,3                ; align buf pointer on next                jz      SHORT aligned_now    ;  dword boundary                Do_CRC_byte                dec     ecx                jnz     align_loopaligned_now:    ENDIF ; !NO_32_BIT_LOADS                mov     edx,ecx              ; save len in edx                shr     ecx,3                ; ecx = len / 8                jz      SHORT No_Eights    IFNDEF NO_ALIGN; align loop head at start of 486 internal cache line !!                align   16    ENDIFNext_Eight:    IFNDEF  NO_32_BIT_LOADS                Do_CRC_dword                Do_CRC_dword    ELSE ; NO_32_BIT_LOADS                Do_CRC_byte                Do_CRC_byte                Do_CRC_byte                Do_CRC_byte                Do_CRC_byte                Do_CRC_byte                Do_CRC_byte                Do_CRC_byte    ENDIF ; ?NO_32_BIT_LOADS                dec     ecx                jnz     Next_EightNo_Eights:                mov     ecx,edx                and     ecx,000000007H       ; ecx = len % 8    ENDIF ; !NO_UNROLLED_LOOPS                jz      SHORT bail           ;>   if (len)    IFNDEF NO_ALIGN; align loop head at start of 486 internal cache line !!                align   16    ENDIFloupe:                                       ;>     do {                Do_CRC_byte                  ;        c = CRC32(c, *buf++);                dec     ecx                  ;>     } while (--len);                jnz     loupebail:                                        ;> }                not     eax                  ;> return ~c;fine:                pop     ecx                pop     edx                pop     ebx                pop     esi                pop     edi                STD_LEAVE                ret_crc32          endp_TEXT   ends;    ENDIF ; !USE_ZLIB;end

⌨️ 快捷键说明

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