Blog. Just Blog

Распаковка данных в формате ZX7 Mini на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Распаковка данных в формате ZX7 Mini на Ассемблере
Распаковка данных в формате ZX7 Mini на Ассемблере

ZX7 Mini за авторством Antonio Jose Villena Godoy - алгоритм упаковки и распаковки, который используется в ZX-Spectrum. Он основан на алгоритме ZX7 от Einar Saukas, но код распаковщика получился более компактным. По степени компрессии алгоритм находится в "третьей тройке игроков", примерно на уровне оригинального LZ77.

Утилиту для упаковки можно скачать с официального репозитория, но на всякий случай я продублировал ее в прилагаемый архив. Исходники алгоритма открыты, их тоже можно взять на сайте автора.
  1. ;------------------------------------------------------------
  2. ; Распаковка данных в формате ZX7 Mini
  3. ;------------------------------------------------------------
  4. ; На входе:
  5. ;   lpCompressed - указатель на упакованные данные
  6. ;   lpOut - указатель на буфер для распакованных данных
  7. ; На выходе:
  8. ;   EAX = размер распакованных данных
  9. ;------------------------------------------------------------
  10. proc zx7_unpack lpCompressed:DWORD,lpOut:DWORD
  11.         pusha
  12.  
  13.         mov     esi,[lpCompressed]
  14.         mov     edi,[lpOut]
  15.  
  16.         mov     al,80h
  17. .literal:
  18.         movsb
  19. .unpack:
  20.         stdcall .get_bit
  21.         jnc     .literal
  22.         push    1
  23.         pop     ecx
  24. .get_len:
  25.         stdcall .get_bit
  26.         rcl     cl, 1
  27.         jc      .exit_unpack
  28.         stdcall .get_bit
  29.         jnc     .get_len
  30.         push    esi
  31.         movzx   edx,byte[esi]
  32.         mov     esi,edi
  33.         sbb     esi,edx
  34.         rep     movsb
  35.         pop     esi
  36.         inc     esi
  37.         jmp    .unpack
  38. .exit_unpack:
  39.         sub     edi,[lpOut]
  40.         mov     [esp+28],edi
  41.         popa
  42.         ret
  43.  
  44. .get_bit:
  45.         add     al,al
  46.         jnz     .exit_get_bit
  47.         lodsb
  48.         adc     al,al
  49. .exit_get_bit:
  50.         retn
  51. endp
В качестве параметров передается указатель на упакованные данные и указатель на буфер-приемник. На выходе в регистре EAX возвращается количество байт, которое было извлечено из сжатых данных. Размер принимающего буфера в процессе распаковки никак не проверяется, об этом вы должны позаботиться самостоятельно.

Так как размер исходных данных заранее не определен, перед распаковкой его надо обязательно узнать, чтобы выделить соответствующий объем памяти. Для этого я сделал следующую функцию.
  1. ;---------------------------------------------------
  2. ; Получение размера распакованных данных
  3. ;---------------------------------------------------
  4. ; На входе:
  5. ;   lpCompressed - указатель на упакованные данные
  6. ; На выходе:
  7. ;   EAX = размер распакованных данных
  8. ;---------------------------------------------------
  9. proc zx7_size lpCompressed:DWORD
  10.         pusha
  11.  
  12.         mov     esi,[lpCompressed]
  13.         xor     edi,edi
  14.  
  15.         mov     al,80h
  16. .literal:
  17.         inc     esi
  18.         inc     edi
  19. .unpack:
  20.         stdcall .get_bit
  21.         jnc     .literal
  22.         push    1
  23.         pop     ecx
  24. .get_len:
  25.         stdcall .get_bit
  26.         rcl     cl, 1
  27.         jc      .exit_unpack
  28.         stdcall .get_bit
  29.         jnc     .get_len
  30.         add     edi,ecx
  31.         inc     esi
  32.         jmp    .unpack
  33. .exit_unpack:
  34.         mov     [esp+28],edi
  35.         popa
  36.         ret
  37.  
  38. .get_bit:
  39.         add     al,al
  40.         jnz     .exit_get_bit
  41.         lodsb
  42.         adc     al,al
  43. .exit_get_bit:
  44.         retn
  45. endp
В качестве единственного параметра передается указатель на упакованные данные, на выходе в регистре EAX количество байт, которое получится после распаковки.

В приложении пример программы с исходным текстом, которая извлекает из памяти иконку, упакованную по алгоритму ZX7, и выводит ее на форму. Там же в архиве утилита для упаковки и распаковки данных от автора алгоритма.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

ZX7.Mini.Unpack.Demo.zip (9,991 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 801 | Комментариев: 1

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
gob (22.11.2022 в 19:38):
Да, статья устарела. Сейчас стал популярным ZX0.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.1 сек. / MySQL: 2 (0.0073 сек.) / Память: 4.5 Mb
Наверх