📄 hc32.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 + -