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

📄 hc32.inc

📁 一个用汇编写的基于BCE32的压缩和解压引擎
💻 INC
字号:
;Based on benny's BCE32 compress engine,rewrite and bugs fixed by Hume....
;This is a simple DEMO,shows how to compress data based on huffman frequency basis
;1->1
;2->00
;3->010
;4->011
;It's not so complex as stated..
;Well as  you could see,only if the 3+4 < 1,will the data be compressed
;Sorry the ratio is not good....
;I'll try 4bits group next time...
;compiled by MASM32v7,You can use *.bat included in the package to compile
;#################################################################################
;syntax and return values
;a) hC32_compress:   (449 bytes long)
;-------------------
;Input state:
;	1) ESI register - pointer to data, which will be compressed
;	2) EDI register - pointer to memory, where will be placed compressed data
;	3) ECX register - number of bytes to compress + 1 (do not forget "+ 1" !)
;	4) EBX register - work memory (16 bytes)
;	5) EDX register - work memory (16 bytes). MUST NOT be same as EBX !
;
;	call hC32_compress:
;
;Output state:
;	1) EAX register - new size of compressed data(including the data)
;	2) CF set, if negative compression
;	3) Other registers r preserved (except FLAGS)
;Format describing:
;       hc32_header STRUC
;               pure_data_size dd ?
;               orig_data_size dd ?
;               decryption_key  db ?
;       hc32_herder ENDS  
;       

;b) hC32_Decompress:   (266 bytes long)
;---------------------
;Input state:
;	1) ESI register - pointer to compressed data
;	2) EDI register - pointer to memory, where will be placed decompressed data;

;	call hC32_decompress
;
;Output state:
;	1) EAX register - decompressed size maybe real+1 or real_size
;       2) EDX register - real size you  should use this

IF	COMPRESS

size_cbegin:
hC32_compress  proc

;stage 1        
        pushad
      create_table:
        push    ecx
        push    4
        pop     ecx
        lodsb
      c1_table:
        push    eax
        xor     edx,edx
        and     al,3            ;2bits=0
        je      st_end
        cmp     al,1            ;=01
        je      st_1            
        cmp     al,2
        je      st_2            ;=02
      st_3:                     ;=11
        inc     edx
      st_2:
        inc     edx
      st_1:
        inc     edx
      st_end:
        inc     dword ptr [ebx+4*edx]
        pop     eax
        ror     al,2
        loop    c1_table
        pop     ecx
        loop    create_table
        
                  ;lame routine to avoid repetive...
        push    4
        pop     ecx
        xor     edx,edx     ;eax=0 ecx=4 edx=0
      scan_rep: 
        push    ecx
        mov     eax,[ebx+4*edx]
        inc     dword ptr [ebx+4*edx]
        mov     edi,ebx
        push    4
        pop     ecx
        repnz   scasd
        jnz     _next_dword
        inc     dword ptr [ebx+4*edx]
        add     dword ptr [esp],4
      _next_dword:
        dec     dword ptr [ebx+4*edx]
        pop     ecx
        inc     edx
        cmp     dl,3
        jne     n_cl_edx
        cdq
      n_cl_edx:
        loop    scan_rep
        popad
;stage 2
        
        pushad                  ;冒泡排序算法
        clc                     ;No assume
        mov     esi,ebx
        push    3
        pop     ebx
        mov     ecx,ebx

      bb_sort:
        push    ecx
        mov     edi,edx
        push    edx
        LODSD
        mov     edx,eax
      bb2:
        LODSD
        cmp     eax,edx
        jb      no_exswap
        xchg    eax,edx
      no_exswap:
        STOSD
        loop    bb2
        
        mov     eax,edx
        STOSD        
        pop     edx
        pop     ecx
        mov     esi,edx
        loop    bb_sort
        popad
;stage 3                        ;生成编码
        pushad
        clc                     ;No assumptions!!!
                                ;xor    eax,eax push    eax
        push   $zreg()          ;additional syntax
        push    4
        pop    ecx
      n_search:
        pushm   edx,ecx
        lea     esi,[edx+4*eax]
        push    eax
        lodsd
        push    3
        pop     ecx
        xor     edi,edi         ;edi=conter
        push    ebx
      search:
        mov     esi,ebx
        push    eax
        lodsd
        mov     ebp,eax
        pop     eax
        cmp     eax,ebp
        je      end_search
        inc     edi
        add     ebx,4
        loop    search

      end_search:
        pop     ebx
        pop     eax
        inc     eax
        popm    ecx,edx
        rol     byte  ptr [esp],2
        add     [esp],edi        
        loop    n_search
        pop     [esp+pad.Pushad_ebx]
        popad                           ;编码返回在bl中

;stage 4,替换bits 组                        

        pushad
        xor     ebp,ebp
        xor     edx,edx
;        pushad
;__msg OK?
;        popad
        xor     eax,eax
        STOSD                           ;NUM of bytes compressed...==total-4
        mov     eax,[esp+pad.Pushad_ecx]
        STOSD
        mov     [edi],bl
        inc     edi
      next_byte:
        xor     eax,eax
        push    ecx
        lodsb
        push    4
        pop     ecx
      next_bits:
        pushm   ecx,eax
        and     al,3

        push    ebx
        and     bl,3
        cmp     al,bl
        pop     ebx
        je      cb0     ;最高频率 ->1    对应编码1         

        push    ebx     
        ror     bl,2
        and     bl,3
        cmp     al,bl
        pop     ebx
        je      cb1     ;次之频率 ->2   对应编码00  

        push    ebx
        ror     bl,4
        and     bl,3
        cmp     al,bl
        pop     ebx
        je      cb2     ;频率   ->3     对应编码010  
                        
        push    0       ;频率   ->4     对应编码011  
        call    copy_bit
        push    1
        call    copy_bit
      cb0:              ;cb0=1
        push    1
      end_cb1:
        call    copy_bit

        popm    eax,ecx
        ror     al,2
        loop    next_bits
        pop     ecx
        loop    next_byte
        ;--------------------
        cmp     dl,0
        je      all_over_without_remainder
        mov     eax,ebp                 ;有剩余位数的时候
        mov     cl,8
        sub     cl,dl
        rol     al,cl
        stosb
      all_over_without_remainder:

        mov     eax,edi
        sub     eax,[esp+pad.Pushad_edi]
        mov     [esp+pad.Pushad_eax],eax
        popad
        cmp     eax,ecx
        jb      c_ok
        stc
        ret
      c_ok:
        pushm   eax,edi
        sub     eax,(4+4+1)       ;纯粹数据区大小
        stosd        
        popm    edi,eax
        clc
        ret
        ;--------------------
      cb1:
        push    0
      end_cb2:
        call    copy_bit
        push    0
        jmp     end_cb1
      cb2:
        push    0
        call    copy_bit
        push    1
        jmp     end_cb2

      copy_bit:                 ;拷贝压缩编码入缓冲区
        mov     eax,ebp
        shl     al,1     
        or      al,[esp+4]
      cbit:
        inc     edx
        cmp     dl,8
        jne     n_byte
        stosb
        xor     eax,eax
        cdq
      n_byte:
        mov     ebp,eax
        ret     4

hC32_compress  endp
size_c  = $-size_cbegin
ENDIF

IF	DECOMPRESS
size_dbegin:
hC32_decompress proc     
        clc             ;No assume
        lodsd
        mov     ecx,eax ;ECX=NUM
        lodsd
        mov     edx,eax
        pushad
        xor     ebp,ebp  ;clear ebp
        xor     eax,eax
        cdq
        lodsb
        push    eax      ;decryption key
        lodsb
        push    8        ;8
        push    edx      ;0
extract_bits:
        push    ecx
        test    al,80h  ;bits=1          
        jne     extr0
        test    al,0c0h ;bits=00
        je      extr1
        test    al,0a0h
        je      extr2   ;010
        mov     cl,6
        jmp     extr3   ;011

extr0:
        xor     cl,cl                   ;shift bits             1
        mov     byte  ptr [esp+4],1     ;encryption bits width
        jmp     test_bits
extr1:
        mov     cl,2
        mov     byte  ptr [esp+4],2     ;00
        jmp     test_bits
extr2:
        mov     cl,4                    ;010
extr3:
        mov     byte  ptr [esp+4],3     ;011
test_bits:
        pushm   eax,ebx
        mov     ebx,[esp+5*4]
        ror     bl,cl
        call    testb                   ;is 0 or 1,and then copy &store
        ror     bl,1
        call    testb
        popm    ebx,eax

        mov     ecx,[esp+4]
bcopy:  cmp     byte  ptr [esp+8],8
        jne     dnlb
        mov     ebx,eax
        lodsb
        xchg    eax,ebx
        mov     byte  ptr [esp+8],0
        dec     dword ptr [esp]
dnlb:   shl     al,1
        test    bl,80h
        je      nb
        or      al,1        
nb:     rol     bl,1                    ;let al contain the encrypt keys
        inc     byte  ptr [esp+8]
        loop    bcopy
        pop     ecx        
        test    ecx,ecx
        jns     extract_bits

        pop     eax
        pop     eax
        pop     eax
        mov     eax,edi
        sub     eax,[esp+pad.Pushad_edi]
        mov     [esp+pad.Pushad_eax],eax
        popad
        ret
testb:
        test    bl,1
        jne     p1

       
        push    0
_tb_:   mov     eax,ebp
        or      al,[esp]
        ror     al,1
        call    cbit
        ret
 p1:
        push    1
        jmp     _tb_

cbit:                           ;copy bits
        inc     edx
        cmp     dl,8
        jne     n_byte
        stosb
        xor     eax,eax
        cdq  
n_byte:
        mov     ebp,eax 
        ret     4

hC32_decompress endp
size_d  =size_dbegin-$
ENDIF

⌨️ 快捷键说明

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