Export (0) Print
Expand All

2.2.2 E8 Call Translation

E8 call translation is an optional feature that can be used when the data to compress contains x86 instruction sequences. E8 translation operates as a preprocessing stage before compressing each chunk, and the compressed stream (2) header contains a bit that indicates whether the decoder shall reverse the translation as a postprocessing step after decompressing each chunk.

The x86 instruction beginning with a byte value of 0xE8 is followed by a 32-bit, little-endian relative displacement to the call target. When E8 call translation is enabled, the following preprocessing steps are performed on the uncompressed input before compression (assuming little-endian byte ordering):

Let chunk_offset refer to the total number of uncompressed bytes preceding this chunk.

Let E8_file_size refer to the caller-specified value given to the compressor or decoded from the header of the compressed stream (2) during decompression.

The following example shows how E8 translation is performed for each 32-KB chunk of uncompressed data (or less than 32 KB if last chunk to compress).

if (( chunk_offset < 0x40000000 ) && ( chunk_size > 10 ))
   for ( i = 0; i < (chunk_size – 10); i++ )
if ( chunk_byte[ i ] == 0xE8 )
   long current_pointer = chunk_offset + i;
long displacement =    chunk_byte[ i+1 ] |
chunk_byte[ i+2 ] << 8  |
chunk_byte[ i+3 ] << 16 |
chunk_byte[ i+4 ] << 24;
long target = current_pointer + displacement;
if (( target >= 0 ) && ( target < E8_file_size+current_pointer))
if ( target >= E8_file_size )
target = displacement – E8_file_size;
endif
chunk_byte[ i+1 ] = (byte)( target );
chunk_byte[ i+2 ] = (byte)( target >> 8 );
chunk_byte[ i+3 ] = (byte)( target >> 16 );
chunk_byte[ i+4 ] = (byte)( target >> 24 );
endif
   i += 4;
endif
endfor
endif

After decompression, the E8 scanning algorithm is the same. The following example shows how E8 translation reversal is performed.

long value =    chunk_byte[ i+1 ]       |
chunk_byte[ i+2 ] << 8  |
chunk_byte[ i+3 ] << 16 |
chunk_byte[ i+4 ] << 24;

if (( value >= -current_pointer ) && ( value < E8_file_size ))
if ( value >= 0 )
displacement = value – current_pointer;
else
displacement = value + E8_file_size;
endif
chunk_byte[ i+1 ] = (byte)( displacement );
chunk_byte[ i+2 ] = (byte)( displacement >> 8 );
chunk_byte[ i+3 ] = (byte)( displacement >> 16 );
chunk_byte[ i+4 ] = (byte)( displacement >> 24 );
endif

The first bit in the first chunk in the LZXD bitstream (following the 2-byte, chunk-size prefix described in section 2.2.1) indicates the presence or absence of two 16-bit fields immediately following the single bit. If the bit is set, E8 translation is enabled for all the following chunks in the stream (2) using the 32-bit value derived from the two 16-bit fields as the E8_file_size provided to the compressor when E8 translation was enabled. Note that E8_file_size is completely independent of the length of the uncompressed data. E8 call translation is disabled after the 32,768th chunk (after 1 gigabyte (GB) of uncompressed data).

Field

Comments

Size

E8 translation

0-disabled, 1-enabled

1 bit

Translation size high word

Only present if enabled

0 or 16 bits

Translation size low word

Only present if enabled

0 or 16 bits

Show:
© 2014 Microsoft