Copy Link
Add to Bookmark
Report

29A Issue 03 03 08

eZine's profile picture
Published in 
29A
 · 28 Dec 2019

  


;=====================================;
; S T R C ;
;-------------------------------------;
; Super Tiny Reloc Compressor ;
;=====================================;
; Made by Super/29A ;
;=====================================;

Pushd equ 4
Pushad_edi equ 00h
Pushad_esi equ 04h
Pushad_ebp equ 08h
Pushad_esp equ 0ch
Pushad_ebx equ 10h
Pushad_edx equ 14h
Pushad_ecx equ 18h
Pushad_eax equ 1ch


;-----------------------------------------------------------;
; Routine "STRC_max_compress"
;
; Tries different methods and compresses with the best ratio.
;
; INPUT:
; ESI = offset of start of reloc section
; EDI = buffer to store the compressed reloc data
; ECX = number of *bytes* of reloc section (not aligned)
;
; OUTPUT:
; BL = selected method of compression
; (number of bits to encode relative offset)
; ECX = number of *bits* of compressed reloc data
;-----------------------------------------------------------;

STRC_max_compress proc near
push eax
stc
sbb eax,eax ;eax=-1
mov bl,0eh ;try with 14 bits
@@1:
inc ebx
push ecx
call STRC_compress ;compress it
cmp ecx,eax ;this method better?
jnb @@2 ;jump if not
xchg ecx,eax
dec ebx
dec ebx ;go for next method
@@2:
pop ecx
jnz @@1 ;try again if we havent found the perfect method
xchg ecx,eax
pop eax
ret
STRC_max_compress endp


;-----------------------------------------------------------;
; Routine "STRC_compress"
;
; Compresses the reloc section.
;
; INPUT:
; BL = method of compression
; (number of bits to encode relative offset)
; ESI = offset of start of reloc section
; EDI = buffer to store the compressed reloc data
; ECX = number of *bytes* of reloc section (not aligned)
;
; OUTPUT:
; ECX = number of *bits* of compressed reloc data
;-----------------------------------------------------------;

STRC_compress proc near
add ecx,esi ;ecx=end of input buffer
pushad
xor ebp,ebp
xor ebx,ebx ;bit count
@@1:
lodsd
xchg edx,eax ;edx=virtual address
lodsd
lea ecx,[eax-8] ;ecx=size of this block
@@2:
push ecx
push edx
lodsw
sub ah,40h
jnb @@6 ;jump if invalid relocation
add ah,10h
jnb @@6 ;jump if invalid relocation
cwde
add eax,edx ;add the virtual address of actual page
sub eax,ebp ;calculate relative address
add ebp,eax ;update last virtual address
push ebx
db 0fh,0bdh,0d8h ; bsr ebx,eax ;calculate number of bits taken
movzx ecx,byte ptr [esp+(Pushd*3)+Pushad_ebx] ;cl=bits chosen for this method
cmp bl,cl ;we need more bits to store it?
jb @@3 ;nope
shld edx,eax,cl ;
shl eax,cl ;
shr ebx,3 ;
or al,bl ; insert number of bytes needed to store it
lea ecx,[ecx+(ebx*8)+8] ;
@@3:
pop ebx
@@4:
btr [edi],ebx ;
shr edx,1 ;
rcr eax,1 ;
jnb @@5 ;
bts [edi],ebx ; store information bit by bit
@@5: ;
inc ebx ;
loop @@4 ;
@@6:
pop edx
pop ecx
dec ecx
loop @@2 ;next word of actual block
cmp esi,[esp+Pushad_ecx] ;have we processed all blocks?
jb @@1 ;nope
STRC_exit:
mov [esp+Pushad_ecx],ebx ;return number of bits of compressed data
popad
ret
STRC_compress endp


;-----------------------------------------------------------;
; Routine "STRC_decompress"
;
; Decompresses the reloc section.
;
; INPUT:
; BL = method of compression
; (number of bits to encode relative offset)
; ESI = offset of compressed reloc data
; EDI = buffer to store the reloc section
; ECX = number of *bits* of compressed reloc data
;
; OUTPUT:
; ECX = number of *bytes* of decompressed reloc section
;-----------------------------------------------------------;

STRC_decompress proc near
pushad
xor ebp,ebp
xor ebx,ebx
@@1:
cmp ebx,ecx ;have we finished?
jnb @@7 ;nope
push ecx
movzx ecx,byte ptr [esp+(Pushd*1)+Pushad_ebx] ;cl=bits chosen for this method
@@2:
xor eax,eax
push ecx
@@3:
bt [esi],ebx ;
rcr eax,1 ;
inc ebx ; get relative offset
loop @@3 ;
pop ecx ;
rol eax,cl ;
lea ecx,[(eax*8)+8] ;ax=0--> 8 bits
;ax=1--> 16 bits
;ax=2--> 24 bits
;ax=3--> 32 bits
cmp eax,4 ;do we need to read more bits to get the whole relative offset
jb @@2 ;yes
pop ecx
add eax,ebp
dec ebp
mov ebp,eax ;update last virtual address
jns @@5 ;jump if this is not the first time
@@4:
mov eax,ebp
and eax,-1000h
stosd ;store start virtual address of this page
xor eax,eax
mov al,8
mov edx,edi
stosd ;store size of this block
@@5:
mov eax,ebp
sub eax,[edx-4]
cmp eax,1000h
jnb @@7 ;jump if we are in next page
sub ah,-30h ;make it of type 3 :-)
@@6:
stosw ;store relocation
inc dword ptr [edx] ;
inc dword ptr [edx] ; increment block size by two
jb @@1
@@7:
xor eax,eax
test byte ptr [edx],2
jnz @@6 ;align this block if necesary
cmp ebx,ecx ;finished?
jb @@4 ;nope
mov ebx,edi
sub ebx,[esp] ;calculate size of decompressed data
jmp STRC_exit
STRC_decompress endp

;-------------------------------------------------------------------


ends
end start

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT