§ Описание
Ниже представлен код для ассемблера fasm, который распаковывает данные, сжатые через утилиту compress. Она немного отличается от того, что сжимает GIF в деталях. Размер словаря может быть до 256 Кб. Необходимо указать следующие параметры:-
EBX
— стартовый адрес байтовой последовательности (без заголовка LZW) -
ECX
— размер входного файла -
EBP
— адрес начала словаря, временная память -
EDI
— область памяти, куда распаковать
ebx
нужно обязательно пропустить 3 первых байта заголовка, где написано LZW.§ Код на ассемблере
LZW_decompress: mov [.size], ecx ; Окончание потока add [.size], ebx call .init .rept: cmp ebx, [.size] jnb .end ; Декомпрессия закончилась? mov cl, [.bitn] mov eax, [ebx] shr eax, cl ; Сдвинуть на CL бит and eax, [.mask] ; Срезать bitn бит add cl, [.bitk] ; Передвинуть поток mov [.bitn], cl and [.bitn], byte 7 ; Запись в .bitn младших 3 бит movzx ecx, cl shr ecx, 3 add ebx, ecx ; Передвинуть EBX на (CL>>3) cmp eax, 100h jb .single ; ax < 100h -- простой байт je .cmd ; ax = 100h -- команда очистки словаря sub eax, 101h ; Указатель на построенный словарь cmp edx, eax jbe .error ; eax - указатель на словарь если edx <= eax, словарь превышен ; СЛОВАРЬ (8 байт на 1 эл-т) ; 4 | +0 | Количество символов ; 4 | +4 | Указатель на строку для повторения mov ecx, [ebp + 8*eax + 0] ; Длина последовательности mov esi, [ebp + 8*eax + 4] ; Начало ; Скопировать кол-во символов из предыдущего элемента и +1 к длине ; Записать в следующий элемент текущий указатель EDI (построение словаря) lea eax, [ecx + 1] mov [ebp + 8*edx + 0], eax mov [ebp + 8*edx + 4], edi rep movsb jmp .next ; Строительство нового словаря .single: mov [ebp + 8*edx + 0], dword 2 ; Добавить словарь: длина = 2 mov [ebp + 8*edx + 4], edi ; Текущий указатель на выходной поток stosb ; Скопировать один байт из входящего потока .next: ; Добавляем +1 элемент к словарю и переходим далее inc edx cmp edx, [.topnext] jb .rept ; .topnext = [100, 300, 700, F00, 1F00, 3F00, 7F00] mov eax, [.topnext] add eax, 100h add eax, eax sub eax, 100h mov [.topnext], eax inc byte [.bitk] ; Установка новой маски (2^CH)-1 mov cl, [.bitk] mov eax, 1 shl eax, cl dec eax mov [.mask], eax jmp .rept ; Выровнять указатель .cmd: call .init and ebx, 0xFFFFFF0 add ebx, 10h jmp .rept ; Сброс счетчиков и словаря .init: mov [.bitn], byte 0 mov [.bitk], byte 9 mov [.mask], dword 1FFh mov [.topnext], dword 100h xor edx, edx ret .error: stc ; СF=1 Ошибка декомпрессии ret .end: clc ; СF=0 Распаковалось успешно ret ; ---------------------------------------------------------------------- .bitn: db 0 ; Текущий бит 0..7 .bitk: db 9 ; Количество бит .size: dd 0 ; Размер входящего файла .topnext: dd 100h ; Следующий верхний предел словаря .mask: dd 1FFh ; Значение (1^.bitk)-1 ; ----------------------------------------------------------------------
11 дек, 2022
© 2007-2023 Тупил лажовый человек