mirror of
https://github.com/xcat2/xNBA.git
synced 2025-01-21 23:13:14 +00:00
130 lines
3.0 KiB
ArmAsm
130 lines
3.0 KiB
ArmAsm
|
/*
|
||
|
* Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||
|
*
|
||
|
* This file is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License as
|
||
|
* published by the Free Software Foundation; either version 2 of
|
||
|
* the License, or (at your option) any later version.
|
||
|
*
|
||
|
* Originally this code was part of ucl the data compression library
|
||
|
* for upx the ``Ultimate Packer of eXecutables''.
|
||
|
*
|
||
|
* - Converted to gas assembly, and refitted to work with etherboot.
|
||
|
* Eric Biederman 20 Aug 2002
|
||
|
*
|
||
|
* - Structure modified to be a subroutine call rather than an
|
||
|
* executable prefix.
|
||
|
* Michael Brown 30 Mar 2004
|
||
|
*/
|
||
|
|
||
|
|
||
|
.text
|
||
|
.arch i386
|
||
|
.section ".prefix", "ax", @progbits
|
||
|
.code32
|
||
|
|
||
|
.globl decompress
|
||
|
decompress:
|
||
|
/* Save the initial register values */
|
||
|
pushal
|
||
|
|
||
|
/*
|
||
|
* See where I am running, and compute %ebp
|
||
|
* %ebp holds delta between physical and virtual addresses.
|
||
|
*/
|
||
|
call 1f
|
||
|
1: popl %ebp
|
||
|
subl $1b, %ebp
|
||
|
|
||
|
/* "compressed" and "decompress_to" defined by linker script */
|
||
|
/* move compressed image up to temporary area before decompressing */
|
||
|
std
|
||
|
movl $_compressed_size, %ecx
|
||
|
leal _compressed+4-1(%ebp, %ecx), %esi
|
||
|
leal _compressed_copy-1(%ebp, %ecx), %edi
|
||
|
rep movsb
|
||
|
/* Setup to run the decompressor */
|
||
|
cld
|
||
|
leal _compressed_copy(%ebp), %esi
|
||
|
leal decompress_to(%ebp), %edi
|
||
|
movl $-1, %ebp /* last_m_off = -1 */
|
||
|
jmp dcl1_n2b
|
||
|
|
||
|
/* ------------- DECOMPRESSION -------------
|
||
|
|
||
|
Input:
|
||
|
%esi - source
|
||
|
%edi - dest
|
||
|
%ebp - -1
|
||
|
cld
|
||
|
|
||
|
Output:
|
||
|
%eax - 0
|
||
|
%ecx - 0
|
||
|
*/
|
||
|
|
||
|
.macro getbit bits
|
||
|
.if \bits == 1
|
||
|
addl %ebx, %ebx
|
||
|
jnz 1f
|
||
|
.endif
|
||
|
movl (%esi), %ebx
|
||
|
subl $-4, %esi /* sets carry flag */
|
||
|
adcl %ebx, %ebx
|
||
|
1:
|
||
|
.endm
|
||
|
|
||
|
decompr_literals_n2b:
|
||
|
movsb
|
||
|
|
||
|
decompr_loop_n2b:
|
||
|
addl %ebx, %ebx
|
||
|
jnz dcl2_n2b
|
||
|
dcl1_n2b:
|
||
|
getbit 32
|
||
|
dcl2_n2b:
|
||
|
jc decompr_literals_n2b
|
||
|
xorl %eax, %eax
|
||
|
incl %eax /* m_off = 1 */
|
||
|
loop1_n2b:
|
||
|
getbit 1
|
||
|
adcl %eax, %eax /* m_off = m_off*2 + getbit() */
|
||
|
getbit 1
|
||
|
jnc loop1_n2b /* while(!getbit()) */
|
||
|
xorl %ecx, %ecx
|
||
|
subl $3, %eax
|
||
|
jb decompr_ebpeax_n2b /* if (m_off == 2) goto decompr_ebpeax_n2b ? */
|
||
|
shll $8, %eax
|
||
|
movb (%esi), %al /* m_off = (m_off - 3)*256 + src[ilen++] */
|
||
|
incl %esi
|
||
|
xorl $-1, %eax
|
||
|
jz decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */
|
||
|
movl %eax, %ebp /* last_m_off = m_off ?*/
|
||
|
decompr_ebpeax_n2b:
|
||
|
getbit 1
|
||
|
adcl %ecx, %ecx /* m_len = getbit() */
|
||
|
getbit 1
|
||
|
adcl %ecx, %ecx /* m_len = m_len*2 + getbit()) */
|
||
|
jnz decompr_got_mlen_n2b /* if (m_len == 0) goto decompr_got_mlen_n2b */
|
||
|
incl %ecx /* m_len++ */
|
||
|
loop2_n2b:
|
||
|
getbit 1
|
||
|
adcl %ecx, %ecx /* m_len = m_len*2 + getbit() */
|
||
|
getbit 1
|
||
|
jnc loop2_n2b /* while(!getbit()) */
|
||
|
incl %ecx
|
||
|
incl %ecx /* m_len += 2 */
|
||
|
decompr_got_mlen_n2b:
|
||
|
cmpl $-0xd00, %ebp
|
||
|
adcl $1, %ecx /* m_len = m_len + 1 + (last_m_off > 0xd00) */
|
||
|
pushl %esi
|
||
|
leal (%edi,%ebp), %esi /* m_pos = dst + olen + -m_off */
|
||
|
rep
|
||
|
movsb /* dst[olen++] = *m_pos++ while(m_len > 0) */
|
||
|
popl %esi
|
||
|
jmp decompr_loop_n2b
|
||
|
decompr_end_n2b:
|
||
|
/* Restore the initial register values */
|
||
|
popal
|
||
|
ret
|