Распаковка данных в формате ZX7 Mini на Ассемблере
Распаковка данных в формате ZX7 Mini на Ассемблере
ZX7 Mini за авторством Antonio Jose Villena Godoy - алгоритм упаковки и распаковки, который используется в ZX-Spectrum. Он основан на алгоритме ZX7 от Einar Saukas, но код распаковщика получился более компактным. По степени компрессии алгоритм находится в "третьей тройке игроков", примерно на уровне оригинального LZ77.
Утилиту для упаковки можно скачать с официального репозитория, но на всякий случай я продублировал ее в прилагаемый архив. Исходники алгоритма открыты, их тоже можно взять на сайте автора.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------
- ; Распаковка данных в формате ZX7 Mini
- ;------------------------------------------------------------
- ; На входе:
- ; lpCompressed - указатель на упакованные данные
- ; lpOut - указатель на буфер для распакованных данных
- ; На выходе:
- ; EAX = размер распакованных данных
- ;------------------------------------------------------------
- proc zx7_unpack lpCompressed:DWORD,lpOut:DWORD
- pusha
- mov esi,[lpCompressed]
- mov edi,[lpOut]
- mov al,80h
- .literal:
- movsb
- .unpack:
- stdcall .get_bit
- jnc .literal
- push 1
- pop ecx
- .get_len:
- stdcall .get_bit
- rcl cl, 1
- jc .exit_unpack
- stdcall .get_bit
- jnc .get_len
- push esi
- movzx edx,byte[esi]
- mov esi,edi
- sbb esi,edx
- rep movsb
- pop esi
- inc esi
- jmp .unpack
- .exit_unpack:
- sub edi,[lpOut]
- mov [esp+28],edi
- popa
- ret
- .get_bit:
- add al,al
- jnz .exit_get_bit
- lodsb
- adc al,al
- .exit_get_bit:
- retn
- endp
Так как размер исходных данных заранее не определен, перед распаковкой его надо обязательно узнать, чтобы выделить соответствующий объем памяти. Для этого я сделал следующую функцию.
Code (Assembler) : Убрать нумерацию
- ;---------------------------------------------------
- ; Получение размера распакованных данных
- ;---------------------------------------------------
- ; На входе:
- ; lpCompressed - указатель на упакованные данные
- ; На выходе:
- ; EAX = размер распакованных данных
- ;---------------------------------------------------
- proc zx7_size lpCompressed:DWORD
- pusha
- mov esi,[lpCompressed]
- xor edi,edi
- mov al,80h
- .literal:
- inc esi
- inc edi
- .unpack:
- stdcall .get_bit
- jnc .literal
- push 1
- pop ecx
- .get_len:
- stdcall .get_bit
- rcl cl, 1
- jc .exit_unpack
- stdcall .get_bit
- jnc .get_len
- add edi,ecx
- inc esi
- jmp .unpack
- .exit_unpack:
- mov [esp+28],edi
- popa
- ret
- .get_bit:
- add al,al
- jnz .exit_get_bit
- lodsb
- adc al,al
- .exit_get_bit:
- retn
- endp
В приложении пример программы с исходным текстом, которая извлекает из памяти иконку, упакованную по алгоритму ZX7, и выводит ее на форму. Там же в архиве утилита для упаковки и распаковки данных от автора алгоритма.
Просмотров: 801 | Комментариев: 1
Метки: Assembler, распаковка
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
gob
(22.11.2022 в 19:38):
Да, статья устарела. Сейчас стал популярным ZX0.
Добавить комментарий
Заполните форму для добавления комментария