Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; This is LZ-like decompressor. I wish I know the author.
- ; It reads the stream of control words and data bytes and writes the output
- ; according to the control sequences commands:
- ; 1 - copy single byte
- ; 00 - copy, small offset (signed byte), 2..5 bytes to copy (two control bits)
- ; 01 - copy, big offset (13 bits), 2..9 bytes to copy (3 bits),
- ; stored in packed word oooooccc oooooooo, where "o" is offset, "c" is count;
- ; in case of ccc == 000, count is the next byte from stream plus 1.
- ;
- ; Registers usage:
- ; AX - general purpose (control words, data bytes)
- ; SI - source index, offset of packed data
- ; DI - destination index, offset of unpacked data
- ; BP - control word
- ; DX - number of bits in control word remaining
- ; CX - size of block to copy from behind
- ; BX - offset of block to copy from behind (signed int16, negative)
- proc decompress near
- mov dx, 10h ; DX is a bit counter for BP
- lodsw
- mov bp, ax ; BP is a control word (contains bit commands)
- HandleBits:
- shr bp, 1 ; Get the least significant bit (LSB) of BP into CF and shift right BP.
- dec dx
- jnz short GetCopyMode
- ; Read new control word if the old one is exhausted. Below there are several checks like this.
- lodsw
- mov bp, ax
- mov dl, 10h
- GetCopyMode:
- jnb short GetBytesCount ; CF=0, need to count number of bytes to copy
- movsb ; CF=1, single byte needs to be copied
- jmp short HandleBits
- GetBytesCount:
- xor cx, cx ; CX needs to contain number of bytes to copy
- shr bp, 1
- dec dx
- jnz short GetOffsetSize
- lodsw
- mov bp, ax
- mov dl, 10h
- GetOffsetSize:
- jb short ReadBigOffset ; CF=1, offset is big
- shr bp, 1 ; CF=0, offset is small
- dec dx
- jnz short FewBytesToCopy; we need to copy from 2 up to 5 bytes
- lodsw
- mov bp, ax
- mov dl, 10h
- FewBytesToCopy:
- rcl cx, 1 ; get bit 1 of the count from CF into CX LSB
- shr bp, 1
- dec dx
- jnz short LookBehind
- lodsw
- mov bp, ax
- mov dl, 10h
- LookBehind:
- rcl cx, 1 ; get bit 0 of the count from CF into CX LSB
- inc cx ; add 2
- inc cx ; because we won't waste data for 1 bit copying
- lodsb ; time to read offset
- mov bh, 0FFh ; it's gonna be negative 'cause we copy from our tail
- mov bl, al ; now BX contains negative offset
- jmp short CopyDataBytes
- nop ; alignment instruction, never mind
- ReadBigOffset:
- lodsw ; this word is packed
- mov bx, ax ; BL becomes lower part of the offset
- mov cl, 3
- shr bh, cl ; get 5 higher bits of BH
- or bh, 0E0h ; and set 3 higher bits; full offset is constructed
- and ah, 7 ; get 3 lower bits of AH
- jz short LotsBytesToCopy
- mov cl, ah
- inc cx ; in this part we're going to copy from 2 up to 9 bytes, as you see
- inc cx
- CopyDataBytes:
- mov al, [es:bx+di]
- stosb
- loop CopyDataBytes
- jmp short HandleBits
- LotsBytesToCopy:
- lodsb ; in this part, we can copy up to 256 bytes
- or al, al
- jz short UnpackComplete; end of the stream
- mov cl, al ; otherwise, copy some more bytes
- inc cx
- jmp short CopyDataBytes
- UnpackComplete:
- retn
- endp decompress
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement