⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitdcods.s

📁 arm ads1.2 with crack.rar
💻 S
📖 第 1 页 / 共 3 页
字号:
;/*
; * Bit decode assembler
; * Copyright (C) ARM Limited 1998-1999. All rights reserved.
; */

	INCLUDE intworkm.h						; include interworking macros

	AREA	|C$$code|, CODE, READONLY $interwork

	; load and store of halfword operations is required which has specific instructions defined in architecture 4 or later
	; if architecture 4 or later is not available other instructions must be used to simulate the halfword instructions
	;
	; define, therefore, a flag which sets the instructions as appropriate for the architecture supported
	GBLL	ARCHITECTURE_4
	
ARCHITECTURE_4 SETL	:LNOT:( {ARCHITECTURE} = "3" :LOR: {ARCHITECTURE} = "3M" )
	
TABLEBITS	* 10							; length of codeword in bits in the decoding tables that can be decoded directly
											; all remaining codeword lengths over this being decoded by decoding trees
											; this must be the same value used to construct the decoding tables/trees that are passed

; define the local register names used for the functions
fin_stream	RN	0

streamstr	RN	0
n			RN  1
dest		RN  2
lentable	RN  3
symtable	RN  4

source		RN  0
lenwalk 	RN  5
symwalk 	RN  6

bits		RN  7
srcword		RN  8
word		RN  9
dstword		RN 10
symbol		RN 11
codebits	RN 12

t			RN codebits
byte		RN codebits

	INCLUDE	datam.h							; include the load and store operations
	INCLUDE regchekm.h						; include distinct register checking macro
	
GENBITDECODE	EQU	1						; 1 = support general bit decoding function, 0 do not support
											; if this is given as 1, byte, halfword and word data bit decoding are supported
											; regardless of the condition of their flags that follow

BYTEBITDECODE	EQU	1						; 1 = support bit decoding function for byte data, 0 do not support
HWORDBITDECODE	EQU	1						; 1 = support bit decoding function for halfword data, 0 do not support
WORDBITDECODE	EQU	1						; 1 = support bit decoding function for word data, 0 do not support
	
	;---------------------------------------------------------------
	; initialise bit decoding
	;
	; saves registers, gets bit stream and bit position and loads 
	; next two words of data for decoding (if they exist)
	;
	; $streamstr		register: pointer to a structure that must contain
	;					an unsigned character array as first entry that is
	; 					the bitstream to use and an
	;					unsigned integer as second entry that is the
	;					bit position in this array to start from
	; $lentable			register: pointer to decoding length table
	; $symtable			register: pointer to decoding symbol table
	; $lenwalk			register: to hold pointer to decoding length tree
	; $symwalk			register: to hold pointer to decoding symbol tree
	; $bits				register: to hold bit position in the stream
	; $source			register: to hold address of bit stream
	; $srcword			register: to hold current word for decoding
	; $word				register: to hold top-up word for decoding
	; $t				register: temporary
	; $datasize			the size of the symbols
	;
	; $streamstr, $symtable, $lenwalk, $symwalk and $t must be distinct
	; $lentable, $symtable, $lenwalk, $symwalk, $bits, $source, $srcword 
	;		and $word must be distinct
	; $t and $bits must be distinct
	;
	;---------------------------------------------------------------
	MACRO
	INITIALISEBITDECODING $streamstr, $lentable, $symtable, $lenwalk, $symwalk, $bits, $source, $srcword, $word, $t, $datasize
		ASSERT ( $datasize = 8 :LOR: $datasize = 16 :LOR: $datasize = 32 )	; ensure that $datasize is valid
		
		; check registers are distinct
		DISTINCT	$streamstr, $symtable, $lenwalk, $symwalk, $t
		DISTINCT	$lentable, $symtable, $lenwalk, $symwalk, $bits, $source, $srcword, $word
		DISTINCT	$t, $bits
		
		MOV		$t, sp						; save the stack register on entry
		STMFD	sp!, { $streamstr, R4 - R11, lr }	; save registers including the state structure pointer
		LDR		$symtable, [ $t ]			; get the fifth parameter, the symbol table, which is on the stack
		
		ADD		$lenwalk, $lentable, #1 << TABLEBITS	; set the start of tree for lengths, $lentable being bytes
		
		; set the start of tree for symbols which is dependent on the size of the data
		IF $datasize = 8					; $symtable is array of bytes
			ADD		$symwalk, $symtable, #1 << TABLEBITS
		ELSE
			IF $datasize = 16				; $symtable is array of halfwords
				ADD		$symwalk, $symtable, #1 << ( TABLEBITS + 1 )
			ELSE							; $symtable is array of words
				ADD		$symwalk, $symtable, #1 << ( TABLEBITS + 2 )
			ENDIF
		ENDIF
		
		LDMIA	$streamstr, { $source, $bits }	; load bit stream to decode and the bit position to start from in the stream
											
		LDMIA	$source!, { $srcword, $word }	; load in two words of bits from the source stream and increment 
												; the pointer to next un-read position
											; the first word is the first 32-bits for decoding, the second is the
											; refill word used to keep the word being decoded topped up with bits
	
		IF {ENDIAN} = "little"				; the main decoding function operates in big endian mode so if the data is little
			BYTEREV $srcword, $srcword, $t	; endian the bytes need reversing into big endian mode
			BYTEREV $word, $word, $t
		ENDIF

		CMP		$bits, #32					; check if bit position is part way through a word (4 bytes = 32 bits)
		RSBNE	$t, $bits, #32				; if $bits != 32, set $t = 32 - $bits
											; $bits gives the number of bits free in word that keeps decoding word topped up and
											; thus $t gives the number of bits in word for decoding that have previously been
											; decoded and therefore need clearing
		MOVNE	$srcword, $srcword, LSL $t	; re-pack the word being decoded by clearing out the previously decoded bits
											; so that actual next bits for decoding are contained from top bit down 
											; through word
		ORRNE	$srcword, $srcword, $word, LSR bits	; refill word for decoding so that all free bits are now filled with next
													; bits for decoding read from top up word
											; these bits are contained in the top $bits of the top-up word and required 
											; in the bottom $bits of the word for decoding hence the shift right
	MEND

	;---------------------------------------------------------------
	; load data
	;
	; load next codeword length and symbol for given codeword
	;
	; the data read might reference a tree to traverse
	;
	; $lentable			register: memory address of length table
	; $symtable			register: memory address of bytes, 
	;								halfwords or words symbol table
	; $srcword			register: codeword index into the tables
	; $codebits			register: to hold length table data read
	; $symbol			register: to hold symbol data read
	; $datasize			the size of the data items in the array - 8, 16 or 32 bits
	; $indexposinword	the position codeword in $srcword to use as index
	;
	; $symtable must be distinct from $symbol
	; $srcword and $codebits must be distinct
	;
	;---------------------------------------------------------------
	MACRO
	LOADSYMBOLANDLENGTH $lentable, $symtable, $srcword, $codebits, $symbol, $datasize, $indexposinword
		; check registers are distinct
		DISTINCT $srcword, $codebits
		
		; load the next length information from byte length table
		; 255 is returned if symbol to be read describes tree internal node else gives decoded codeword length
		IF $indexposinword = 0				; index given directly in bottom 8 bits
			LDRB	$codebits, [ $lentable, $srcword ]
		ELSE								; index needs shifting into bottom 8 bits first
			LDRB	$codebits, [ $lentable, $srcword, LSR #$indexposinword ]
		ENDIF
		
		; load the next symbol information
		; this references an internal tree node is length is 255 else symbol to decode to
		; this checks the value in datasize
		LOADDATA $symtable, $srcword, $symbol, $symbol, $datasize, $indexposinword
	MEND

	; decode the next codeword to a symbol and length of codeword that has been decoded
	;---------------------------------------------------------------
	; load data
	;
	; load next codeword length and symbol for given codeword
	;
	; the data read might reference a tree to traverse
	;
	; $lentable			register: memory address of length table
	; $symtable			register: memory address of bytes, 
	;								halfwords or words symbol table
	; $srcword			register: word of current data to decode
	; $word				register: top-up word for $srcword
	; $bits				register: number of bits left before $word exhausted
	; $codebits			register: to hold length table data read
	; $symbol			register: to hold symbol data read
	; $datasize			the size of the data items in the array - 8, 16 or 32 bits
	;
	; $symtable must be distinct from $symbol
	; $srcword, $codebits, $bits and $word must be distinct
	;
	;---------------------------------------------------------------
	MACRO
	DECODECODEWORD	$lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, $datasize
		; check registers are distinct
		DISTINCT $bits, $codebits, $srcword, $word
		
		; load next length and symbol information using only bottom TABLEBITS of $srcword as codeword lookup index
		LOADSYMBOLANDLENGTH $lentable, $symtable, $srcword, $codebits, $symbol, $datasize, 32-TABLEBITS

		SUBS	$bits, $bits, $codebits		; calculate the number of bits that will remain in the top-up word before it is
											; after the current codeword is decoded, removed from decoding word and the top-up
											; word used to top-up the decoding word
											; $codebits may at this point be 255 however and thus this may not be true at this point

		MOVGE	$srcword, $srcword, LSL $codebits	; if $bits >= 0, remove the codeword that is being decoded from the decoding
													; word and shift all remaining bits into the top freeing the bottom
		
		; datasize is known to be correct here since it was checked by LOADSYMBOLANDLENGTH
		; set up branch for tree or refilling decoding word based on data size
		IF $datasize = 8					; byte data
			BLLT    tree_or_refill_byte		; if $bits < 0, escape to either perform a tree walk ($codebits = 255) or to
											; refill the top-up word from memory since there are not enough bits left in it
											; to refill the decoding word after the codeword has been decoded
											; (this will happen less often than a straight drop through in either case and thus
											; the code is written so that most cases require minimum number of cycles with 
											; special cases requiring more work)
		ELSE
			IF $datasize = 16				; halfword data
				BLLT	tree_or_refill_hword
			ELSE
				BLLT	tree_or_refill_word	; word data
			ENDIF
		ENDIF
		
		ORR		$srcword, $srcword, $word, LSR $bits	; refill the bottom bits of the word being decoded with the 
														; next bits from the top-up word which are at the top of the word and need
														; shifting down
	MEND

	;---------------------------------------------------------------
	; end bit decoding process
	;
	; save the last bit stream and position reached in the stream 
	; to the structure, restore registers and return
	;
	; $bits				register: number of bits free in $dstword
	; $source			register: bit stream data is decoded from
	; $finaldeststreamaddress
	;					register: to hold final stream structure returned
	; $t				register: temporary
	;
	; $bits, $source, and $t must all be distinct
	;
	;---------------------------------------------------------------
	MACRO
	ENDBITDECODING $bits, $source, $finalstreamaddress, $t
		; check registers are distinct
		DISTINCT $bits, $source, $t
		
		CMP		$bits, #0					; check if top-up word has been completely exhausted
		ADDEQ	$source, $source, #4		; if the top-up word has been exhausted, move to the next memory location to read
											; the next top-up word in else leave the location so that top-up word can be read
											; back in again with current data
		SUB		$source, $source, #8		; subtract two words from pointer so that if the decoder is called again
											; the word for decoding will be read back with the data that is contains now
											; and the top-up word will be the next set of data to read in
		
		
		LDMFD	sp!, { $t }					; read the state structure parameter from the stack that was saved at initialisation
											; the structure is read into $t since $finalstreamaddress could easily be one of
											; $source or $bits which are still required
		STMIA	$t, { $source, $bits }		; store the bit stream pointer reached and number of bits free in top-up word
		MOV		$finalstreamaddress, $t		; set up the return register with the returned structure
		
		RETURN	"R4 - R11","","",""			; decoding complete, restore registers and return (rlist, sp, lr, no condition)
	MEND
	
	;---------------------------------------------------------------
	; decode to an array of bytes
	;
	; decode variable length codewords to byte symbols
	;
	; $nbytes		register: number of bytes to decode
	; $bytedest		register: an array to store bytes decoded
	; $dstword		register: to hold decoded bytes before saving
	; $lentable		register: decoding length table
	; $symtable		register: decoding symbol table
	; $srcword		register: current word being decoded
	; $word			register: top-up for $srcword
	; $bits			register: number of bits before $word is exhausted
	; $codebits		register: to hold each length of codeword being decoded
	; $symbol		register: to hold each decoded symbol
	; $t			register: temporary
	;
	; $nbytes, $bytedest, $dstword, $lentable, $symtable, $srcword, $word,
	; $bits, $codebits and $symbol must all be distinct
	;
	; $t must be distinct from all registers except $codebits and $symbol
	;
	;---------------------------------------------------------------
	MACRO
	DECODETOBYTES $nbytes, $bytedest, $dstword, $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, $t
		; check registers are distinct
		DISTINCT $nbytes, $bytedest, $dstword, $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol
		DISTINCT $t, $nbytes, $bytedest, $dstword, $lentable, $symtable, $srcword, $word, $bits
		
		SUBS	$nbytes, $nbytes, #4		; check that there are at least 4 bytes (1 word)...
		BLT		%FT7 ; decode_bytes			; ...if <4 bytes, cannot operate on words so process as bytes
		
		ANDS	$t, $bytedest, #3			; check that pointer is word-aligned (low 2-bits clear)...
		BEQ		%FT0 ; get_4_decoded_bytes	; ...if word aligned begin processing over words
		
		LDR		$dstword, [$bytedest, -$t]!	; ...else get initial (incomplete) destination word
											; adjusting the pointer to make it word-aligned and leave the
											; pointer in its adjusted state

		ADD		$nbytes, $nbytes, $t		; 4 has already been subtracted for word operations, however the
											; byte offset for pointer indicates how many bytes have already been
											; decoded into the destination and thus how many less will be
											; decoded for the first word
	
		CMP		$t, #2						; comparison used for branch to operate on bytes obtained
		IF {ENDIAN} = "little"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -