Кузнецов Алексей Васильевич : другие произведения.

Саморазжимающиеся данные

Самиздат: [Регистрация] [Найти] [Рейтинги] [Обсуждения] [Новинки] [Обзоры] [Помощь|Техвопросы]
Ссылки:


 Ваша оценка:

Многие программисты пользуются программой PKLite фирмы PKWare. Эта программа сжимает EXE- и COM-файлы. При сжатии этих файлов PKLITE'ом их объём уменьшается, а работают они так же, как и раньше. Разжимает программу в памяти PKLITE практически мгновенно.

А нельзя ли использовать эту удобную утилиту для уменьшения объёма файлов, содержащих данные? Конечно, при этом можно сжимать не любые данные, а только те, которые будут использоваться в ВАШЕЙ программе.

Сделать это очень просто. Для этого нужно дописать в начало данных маленький блок, сжать данные PKLITE'ом, а затем из главной программы с помощью процедуры EXEC загрузить и выполнить данные. Блок кода, который дописывается в начало данных, узнаёт, в какой точке находятся загруженные данные, и выходит в родительскую программу.

Вот пример кода, дописываемого в начало файла для размера данных не более 64 K (создание COM-файла):
	xor	ax, ax
	mov	ds, ax
	mov	word ptr ds:[7Ch], cs
	ret
В шестнадцатеричном коде это выглядит так: 33, C0, 8E, D8, 8C, 0E, 7C, 00, C3.

Как видите, при запуске и выполнении этого файла с данными он запишет по адресу 0000:007C значение сегмента кода. После возврата в главную программу будет известно, где начинаются загруженные данные. Адрес 0000:007C - это вектор прерывания графических символов 1Fh. Мы посылаем CS туда потому, что переменные родительской программы будут недоступны.

Такой способ сжатия очень удобен для загрузки картинок и оверлеев. При этом программисту не нужно писать свой упаковщик. Я, например, успешно применяю PKLITE для сжатия картинок в играх.

Но и у этого способа есть два основных недостатка. Первый: нужно всегда оставлять немного свободной памяти, необходимой для разворачивания файла. Второй: все сжатые файлы с данными должны создаваться во время написания главной программы.

Вот программа, которая демонстрирует запуск и вывод на экран картинки для CGA адаптера размером 16000 байт:

{$M 1024,0,0}      {Heap - 0 байт. Всегда должно быть достаточно памяти,
                   чтобы запустить и распаковать картинку.}
uses Dos;
var
  OldVec, w: Word;
Begin
  OldVec:=memW[0,$7C];  {Запоминаем старый вектор 1Fh}
  Exec('SCREEN');       {"Запуск" и разжатие картинки}
  asm
   mov	   ax, 4	{Переход в графический CGA режим}
   int     10h
  end;
  w:=memW[0:$7C]+$10;   {Узнаём сегмент кода 
                        загруженной программы + размер PSP}
  move(mem[w:9], mem[$B800:0], 8000);      {Вывод картинки}
  move(mem[w:8009], mem[$BA00:0], 8000);   {...}
  asm
   xor	   ax, ax	{Ожидание нажатия клавиши}
   int	   16h
   mov	   ax, 3        {Возврат в текстовый режим}
   int	   10h
  end;
  memW[0:$7C]:=OldVec   {Возвращаем старое значение вектора 1Fh}
End.

[ IndexPro 1'95 ]
 Ваша оценка:

Связаться с программистом сайта.

Новые книги авторов СИ, вышедшие из печати:
О.Болдырева "Крадуш. Чужие души" М.Николаев "Вторжение на Землю"

Как попасть в этoт список
Сайт - "Художники" .. || .. Доска об'явлений "Книги"