Dec 292017
 
How to reduce the memory requirement for loading an EXE file compressed with LZEXE.
File LZEMEM.ZIP from The Programmer’s Corner in
Category Tutorials + Patches
How to reduce the memory requirement for loading an EXE file compressed with LZEXE.
File Name File Size Zip Size Zip Type
LZEXEMEM.TXT 10675 3653 deflated

Download File LZEMEM.ZIP Here

Contents of the LZEXEMEM.TXT file


How to Reduce the Memory Requirement
for Loading an EXE File Compressed with LZEXE

by Pete Petrakis
CIS 76555,1175


LZEXE is a program that can greatly reduce the disk size of most EXE
files. The compressed files remain executable and they expand themselves
very rapidly when they are run. Except for very large programs, the auto-
decompression time for an LZEXE-compressed EXE file is too short to
be noticeable. Even with very large programs the delay is barely
noticeable, amounting to perhaps only a second or two of additional time.
Disk file size reductions usually are in the range of 30-40 percent, although
I've gotten compressions as high as 67-71 percent on a few EXE files.
The compressions are comparable to those achieved with PKZIP and
LHARC. In fact those archiving programs rarely can add anything to a
compression already achieved with LZEXE, and they simply store such
files unchanged in the archive file. The program's author, Fabrice Bellard
of Grabels, France deserves great respect for an excellent piece of work.

A frequent result of compression with LZEXE is a significant increase
in the amount of memory required to load the program. This can be seen
with Microsoft's EXEMOD program (which is included with some of its
language packages). When run with only an EXE file name on its
command line, EXEMOD reveals information about the program such as
disk file size, minimum memory needed to load, stack space, minimum
allocation, and maximum allocation. When run with appropriate command
line switches, EXEMOD allows some of the values to be changed.

One author of a rather large program found that compression with
LZEXE reduced the disk file size of his program from 183k to 112k but
added nearly 100k of minimum load memory to the 211k the program
needed in the uncompressed form. He concluded, "I can't pay that price."
The good news I have for that author (and for others who might be
similarly dismayed) is that there is a way to eliminate most or all of the
increment in the minimum load requirement that occurs when files are
compressed with LZEXE.

The method is one I stumbled upon purely by trial and error, with
countless reboots required because of a locked system. It involves
Microsoft's EXEMOD program.

I couldn't begin to explain why this empirical method works. The
documentation for EXEMOD that I've read explains WHAT can be
changed with that program, and it tells HOW to do it. But it says not
one word about WHEN, WHY, and HOW MUCH to change anything.
Since Microsoft provides absolutely no guidance on the intelligent use of
EXEMOD, people like me have no alternative but to use it stupidly. If
Microsoft or anybody else can tell me why the method I groped my way
to works, I'll be grateful.

Anyway, here is the method, step by step:


1. Examine the uncompressed file data with EXEMOD by typing

EXEMOD filename

at the DOS prompt. You will get a table that looks something
this:


CAL (hex) (dec)

.EXE size (bytes) 2CDA2 183714
Minimum load size (bytes) 334F2 210162
Overlay number 0 0
Initial CS:IP 0000:0000
Initial SS:SP 30A4:0C00 3072
Minimum allocation (para) 695 1685
Maximum allocation (para) FFFF 65535
Header size (para) 20 32
Relocation table offset 1E 30
Relocation entries 0 0


This example happens to be data for the uncompressed version
of the program (CAL.EXE) I mentioned earlier -- the one that
acquired an additional 100k of minimum load size after
compression with LZEXE.

2. Compress the file with LZEXE and run EXEMOD again to
analyze it. Here is what EXEMOD reports about the same
program after compression with LZEXE:

CAL (hex) (dec)

.EXE size (bytes) 1B65D 112221
* Minimum load size (bytes) 4524D 283213
Overlay number 0 0
Initial CS:IP 1B48:0012
Initial SS:SP 2D31:0080 128
* Minimum allocation (para) 29C1 10689
* Maximum allocation (para) FFFF 65535
Header size (para) 2 2
Relocation table offset 1C 28
Relocation entries 0 0


Notice that the EXE file size has been reduced from 184k to
112k, a saving of 72k. But the three lines that matter most for
this discussion are Minimum load size, Minimum allocation,
and Maximum allocation. They are marked with asterisks here
so you can spot them quickly.

Compare the value for Minimum load size in the two tables.
Notice the increase of 72k for Minimum load size after
compression with LZEXE. We are going to reduce that number
drastically in the next step, but before taking the next step
we'll need to note the new hex value for Minimum allocation.
In actual practice it's a good idea to write it down before
proceeding. Note that the Minimum allocation in this example is
29C1 hex (we won't need the decimal value).

3. Run EXEMOD again, this time to change the maximum and
minimum allocations. This is the crucial step, and it involves
using EXEMOD to do two things: (1) change the maximum
allocation to the value for minimum allocation that was found
in the previous step, and (2) change the minimum allocation to
zero. Using the same program as an example we type the
following at the DOS prompt:

EXEMOD CAL /MAX 29C1 /MIN 0

As EXEMOD does its work, the following message appears:

EXEMOD : warning U4051: minimum allocation less than
stack; correcting minimum

Ignore it.


4. Run EXEMOD again to see what happened (just type EXEMOD
and program name, without any switches). Here is what we
find for this example:

CAL (hex) (dec)

.EXE size (bytes) 1B65D 112221
Minimum load size (bytes) 2D38D 185229
Overlay number 0 0
Initial CS:IP 1B48:0012
Initial SS:SP 2D31:0080 128
Minimum allocation (para) 11D5 4565
Maximum allocation (para) 29C1 10689
Header size (para) 2 2
Relocation table offset 1C 28
Relocation entries 0 0


Notice that the Minimum load size of the compressed program is
greatly reduced. It's actually smaller than it was before
compression with LZEXE. We have reduced the disk file size
from 184k to 112k with LZEXE, and we have also reduced the
memory needed to load the program from 210k to 185k, 25k lower
than it was before compression.

Now for a practical test. After the compressed program was processed
by the method just described, it could be loaded and run in a system with
only 255k of total free RAM. This was an absolute minimum determined
by using EATMEM, a program that lets you whittle down available RAM
to any amount you want for test purposes. That minimum required RAM
size after LZEXE compression and processing with EXEMOD is within
only 2 or 3k of the minimum available RAM that was needed before
compression (also determined by using EATMEM).

End result: a nearly 40 percent reduction in disk file size and no
significant change in memory requirements.

The essence of the method is making the minimum allocation become
the maximum allocation and setting the minimum allocation to zero (thus
forcing EXEMOD to determine what the new minimum allocation should
actually be).

Understand that I had absolutely no rationale for doing it this way. It
is purely the result of many stabs in the dark. I had to have some number
to plug into EXEMOD for maximum allocation, and since I had no
rational basis for picking one I simply used the one that was already there
for minimum allocation. Then, because I didn't know what to put in for
minimum allocation, I made it zero, in effect telling EXEMOD, "You
figure it out." Surely there is a way to select values for minimum and
maximum allocations intelligently and purposefully, but until Microsoft sees
fit to tell us what it is, this blind, ignorant method will have to suffice, at
least for me. I have tested my empirical method with many LZEXE-
compressed programs, and so far it has substantially reduced the minimum
load size every time. And the programs always work. Usually the
resulting minimum load size is smaller than it was before compression with
LZEXE. Don't ask me why.

That's about it. Maybe you can (1) explain why this method works and
(2) provide a method for choosing numbers for maximum and minimum
allocation that is grounded in theory rather than groping and rebooting.


Pete Petrakis



NOTE: Since writing this I have written a shell program that does it all
automatically. It runs LZEXE to compress your EXE file, and it runs
EXEMOD to set the load memory requirement lower. The program is called
LZEFIX, and the method it uses is identical to what's described here.
It does exactly what you would do -- run EXEMOD, read screens, and make
changes. LZEFIX is on Compuserve (IBMSYS and MSSYS) and may soon spread
to other systems. It could have a short life if the author of LZEXE fixes
his program to give compressed programs a more reasonable memory
requirement for loading, and that would be fine with me.


 December 29, 2017  Add comments

Leave a Reply