Guest User

LZ-like Decompressor

a guest
Jan 3rd, 2016
848
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; This is LZ-like decompressor. I wish I know the author.
  2. ; It reads the stream of control words and data bytes and writes the output
  3. ; according to the control sequences commands:
  4. ; 1  - copy single byte
  5. ; 00 - copy, small offset (signed byte), 2..5 bytes to copy (two control bits)
  6. ; 01 - copy, big offset (13 bits), 2..9 bytes to copy (3 bits),
  7. ;      stored in packed word oooooccc oooooooo, where "o" is offset, "c" is count;
  8. ;      in case of ccc == 000, count is the next byte from stream plus 1.
  9. ;
  10. ; Registers usage:
  11. ; AX - general purpose (control words, data bytes)
  12. ; SI - source index, offset of packed data
  13. ; DI - destination index, offset of unpacked data
  14. ; BP - control word
  15. ; DX - number of bits in control word remaining
  16. ; CX - size of block to copy from behind
  17. ; BX - offset of block to copy from behind (signed int16, negative)
  18.  
  19. proc    decompress near
  20.         mov dx, 10h             ; DX is a bit counter for BP
  21.         lodsw
  22.         mov bp, ax              ; BP is a control word (contains bit commands)
  23.  
  24. HandleBits:
  25.         shr bp, 1               ; Get the least significant bit (LSB) of BP into CF and shift right BP.
  26.         dec dx
  27.         jnz short GetCopyMode
  28. ; Read new control word if the old one is exhausted. Below there are several checks like this.
  29.         lodsw
  30.         mov bp, ax
  31.         mov dl, 10h
  32.  
  33. GetCopyMode:
  34.         jnb short GetBytesCount ; CF=0, need to count number of bytes to copy
  35.         movsb                   ; CF=1, single byte needs to be copied
  36.         jmp short HandleBits
  37.  
  38. GetBytesCount:
  39.         xor cx, cx              ; CX needs to contain number of bytes to copy
  40.         shr bp, 1
  41.         dec dx
  42.         jnz short GetOffsetSize
  43.         lodsw
  44.         mov bp, ax
  45.         mov dl, 10h
  46.  
  47. GetOffsetSize:
  48.         jb  short ReadBigOffset ; CF=1, offset is big
  49.         shr bp, 1               ; CF=0, offset is small
  50.         dec dx
  51.         jnz short FewBytesToCopy; we need to copy from 2 up to 5 bytes
  52.         lodsw
  53.         mov bp, ax
  54.         mov dl, 10h
  55.  
  56. FewBytesToCopy:
  57.         rcl cx, 1               ; get bit 1 of the count from CF into CX LSB
  58.         shr bp, 1
  59.         dec dx
  60.         jnz short LookBehind
  61.         lodsw
  62.         mov bp, ax
  63.         mov dl, 10h
  64.  
  65. LookBehind:
  66.         rcl cx, 1               ; get bit 0 of the count from CF into CX LSB
  67.         inc cx                  ; add 2
  68.         inc cx                  ; because we won't waste data for 1 bit copying
  69.         lodsb                   ; time to read offset
  70.         mov bh, 0FFh            ; it's gonna be negative 'cause we copy from our tail
  71.         mov bl, al              ; now BX contains negative offset
  72.         jmp short CopyDataBytes
  73.         nop                     ; alignment instruction, never mind
  74.  
  75. ReadBigOffset:
  76.         lodsw                   ; this word is packed
  77.         mov bx, ax              ; BL becomes lower part of the offset
  78.         mov cl, 3
  79.         shr bh, cl              ; get 5 higher bits of BH
  80.         or  bh, 0E0h            ; and set 3 higher bits; full offset is constructed
  81.         and ah, 7               ; get 3 lower bits of AH
  82.         jz  short LotsBytesToCopy
  83.         mov cl, ah
  84.         inc cx                  ; in this part we're going to copy from 2 up to 9 bytes, as you see
  85.         inc cx
  86.  
  87. CopyDataBytes:
  88.         mov al, [es:bx+di]
  89.         stosb
  90.         loop    CopyDataBytes
  91.         jmp short HandleBits
  92.  
  93. LotsBytesToCopy:
  94.         lodsb                   ; in this part, we can copy up to 256 bytes
  95.         or  al, al
  96.         jz  short UnpackComplete; end of the stream
  97.         mov cl, al              ; otherwise, copy some more bytes
  98.         inc cx
  99.         jmp short CopyDataBytes
  100.  
  101. UnpackComplete:
  102.         retn
  103. endp    decompress
RAW Paste Data