source: bootcd/isolinux/syslinux-6.03/gpxe/src/arch/i386/prefix/unnrv2b.S

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
3 *
4 * This file is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * Originally this code was part of ucl the data compression library
10 * for upx the ``Ultimate Packer of eXecutables''.
11 *
12 * - Converted to gas assembly, and refitted to work with etherboot.
13 *   Eric Biederman 20 Aug 2002
14 *
15 * - Structure modified to be a subroutine call rather than an
16 *   executable prefix.
17 *   Michael Brown 30 Mar 2004
18 *
19 * - Modified to be compilable as either 16-bit or 32-bit code.
20 *   Michael Brown 9 Mar 2005
21 */
22
23FILE_LICENCE ( GPL2_OR_LATER )
24
25/****************************************************************************
26 * This file provides the decompress() and decompress16() functions
27 * which can be called in order to decompress an image compressed with
28 * the nrv2b utility in src/util.
29 *
30 * These functions are designed to be called by the prefix.  They are
31 * position-independent code.
32 *
33 * The same basic assembly code is used to compile both
34 * decompress() and decompress16().
35 ****************************************************************************
36 */
37
38        .text
39        .arch i386
40        .section ".prefix.lib", "ax", @progbits
41
42#ifdef CODE16
43/****************************************************************************
44 * decompress16 (real-mode near call, position independent)
45 *
46 * Decompress data in 16-bit mode
47 *
48 * Parameters (passed via registers):
49 *   %ds:%esi - Start of compressed input data
50 *   %es:%edi - Start of output buffer
51 * Returns:
52 *   %ds:%esi - End of compressed input data
53 *   %es:%edi - End of decompressed output data
54 *   All other registers are preserved
55 *
56 * NOTE: It would be possible to build a smaller version of the
57 * decompression code for -DKEEP_IT_REAL by using
58 *    #define REG(x) x
59 * to use 16-bit registers where possible.  This would impose limits
60 * that the compressed data size must be in the range [1,65533-%si]
61 * and the uncompressed data size must be in the range [1,65536-%di]
62 * (where %si and %di are the input values for those registers).  Note
63 * particularly that the lower limit is 1, not 0, and that the upper
64 * limit on the input (compressed) data really is 65533, since the
65 * algorithm may read up to three bytes beyond the end of the input
66 * data, since it reads dwords.
67 ****************************************************************************
68 */
69
70#define REG(x) e ## x
71#define ADDR32 addr32
72
73        .code16
74        .globl  decompress16
75decompress16:
76       
77#else /* CODE16 */
78
79/****************************************************************************
80 * decompress (32-bit protected-mode near call, position independent)
81 *
82 * Parameters (passed via registers):
83 *   %ds:%esi - Start of compressed input data
84 *   %es:%edi - Start of output buffer
85 * Returns:
86 *   %ds:%esi - End of compressed input data
87 *   %es:%edi - End of decompressed output data
88 *   All other registers are preserved
89 ****************************************************************************
90 */
91
92#define REG(x) e ## x
93#define ADDR32
94       
95        .code32
96        .globl  decompress
97decompress:
98
99#endif /* CODE16 */
100
101#define xAX     REG(ax)
102#define xCX     REG(cx)
103#define xBP     REG(bp)
104#define xSI     REG(si)
105#define xDI     REG(di)
106
107        /* Save registers */
108        push    %xAX
109        pushl   %ebx
110        push    %xCX
111        push    %xBP
112        /* Do the decompression */
113        cld
114        xor     %xBP, %xBP
115        dec     %xBP            /* last_m_off = -1 */
116        jmp     dcl1_n2b
117       
118decompr_literals_n2b:
119        ADDR32 movsb
120decompr_loop_n2b:
121        addl    %ebx, %ebx
122        jnz     dcl2_n2b
123dcl1_n2b:
124        call    getbit32
125dcl2_n2b:
126        jc      decompr_literals_n2b
127        xor     %xAX, %xAX
128        inc     %xAX            /* m_off = 1 */
129loop1_n2b:
130        call    getbit1
131        adc     %xAX, %xAX      /* m_off = m_off*2 + getbit() */
132        call    getbit1
133        jnc     loop1_n2b       /* while(!getbit()) */
134        sub     $3, %xAX
135        jb      decompr_ebpeax_n2b      /* if (m_off == 2) goto decompr_ebpeax_n2b ? */
136        shl     $8, %xAX       
137        ADDR32 movb (%xSI), %al /* m_off = (m_off - 3)*256 + src[ilen++] */
138        inc     %xSI
139        xor     $-1, %xAX
140        jz      decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */
141        mov     %xAX, %xBP      /* last_m_off = m_off ?*/
142decompr_ebpeax_n2b:
143        xor     %xCX, %xCX
144        call    getbit1
145        adc     %xCX, %xCX      /* m_len = getbit() */
146        call    getbit1
147        adc     %xCX, %xCX      /* m_len = m_len*2 + getbit()) */
148        jnz     decompr_got_mlen_n2b    /* if (m_len == 0) goto decompr_got_mlen_n2b */
149        inc     %xCX            /* m_len++ */
150loop2_n2b:
151        call    getbit1
152        adc     %xCX, %xCX      /* m_len = m_len*2 + getbit() */
153        call    getbit1
154        jnc     loop2_n2b       /* while(!getbit()) */
155        inc     %xCX
156        inc     %xCX            /* m_len += 2 */
157decompr_got_mlen_n2b:
158        cmp     $-0xd00, %xBP
159        adc     $1, %xCX        /* m_len = m_len + 1 + (last_m_off > 0xd00) */
160        push    %xSI
161        ADDR32 lea (%xBP,%xDI), %xSI    /* m_pos = dst + olen + -m_off  */
162        rep
163        es ADDR32 movsb         /* dst[olen++] = *m_pos++ while(m_len > 0) */
164        pop     %xSI
165        jmp     decompr_loop_n2b
166
167
168getbit1:
169        addl    %ebx, %ebx
170        jnz     1f
171getbit32:
172        ADDR32 movl (%xSI), %ebx
173        sub     $-4, %xSI       /* sets carry flag */
174        adcl    %ebx, %ebx
1751:
176        ret
177
178decompr_end_n2b:
179        /* Restore registers and return */
180        pop     %xBP
181        pop     %xCX
182        popl    %ebx
183        pop     %xAX
184        ret
Note: See TracBrowser for help on using the repository browser.