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

📄 lzs.asm

📁 lharc压缩算法
💻 ASM
📖 第 1 页 / 共 2 页
字号:
page	66, 120					;
;$_init						;
;***********************************************;
;       LHarc version 1.13b (c) Yoshi 1988-89.	;
;           LZSS module : 1989/ 5/14		;
;						;
;       偙偺晹暘偼丄墱懞惏旻巵偺俴倅俙俼俬朄偺	;
;       俠僜乕僗傪嶲峫偵婰弎偟偨丅		;
;       傑偨丄崅懍壔偺偨傔偵嶰栘榓旻巵偺 LArc	;
;       偺僜乕僗儕僗僩傪嶲峫偵偝偣偰捀偄偨丅	;
;						;
; HTAB = 8					;
;***********************************************;
						;
extrn	__fgetc:near				;
extrn	__fputc:near				;
						;
;***************************************	;
;	getc macro				;
;	    bx: address of FILE struc		;
;	    ax: input char (return)		;
;***************************************	;
getc@	macro					;
	local	getc1, getc2			;
	dec	word ptr [bx]			;
	jl	getc1				;
	inc	word ptr [bx+10]		;
	mov	bx, [bx+10]			;
	mov	al, [bx-1]			;
	xor	ah, ah				;
	jmp	getc2				;
getc1:						;
	push	dx				;
	push	cx				;
	push	bx				;
	call	__fgetc				;
	pop	bx				;
	pop	cx				;
	pop	dx				;
getc2:						;
	endm					;
						;
getc_crc@	macro				;
	local	getc1, getc2			;
	dec	word ptr [bx]			;
	jl	getc1				;
	inc	word ptr [bx+10]		;
	mov	bx, [bx+10]			;
	mov	al, [bx-1]			;
	xor	ah, ah				;
	jmp	getc2				;
getc1:						;
	call	crcgetc				;
getc2:						;
	endm					;
						;
;***************************************	;
;	putc macro				;
;	    ax: output char			;
;	    bx: address of FILE struc		;
;***************************************	;
putc@	macro					;
	local	putc1, putc2			;
	inc	word ptr [bx]			;
	jge	putc1				;
	inc	word ptr [bx+10]		;
	mov	bx, [bx+10]			;
	mov	[bx-1], al			;
	jmp	short putc2			;
putc1:						;
	call	fputc				;
putc2:						;
	endm					;
						;
putc_crc@	macro				;
	local	putc1, putc2			;
	inc	word ptr [bx]			;
	jge	putc1				;
	inc	word ptr [bx+10]		;
	mov	bx, [bx+10]			;
	mov	[bx-1], al			;
	jmp	short putc2			;
putc1:						;
	call	crcputc				;
putc2:						;
	endm					;
						;
DGROUP	group	_DATA,_BSS			;
EGROUP	group	_EXTRA				;
						;
	name	lzsub				;
_TEXT	segment	byte public 'CODE'		;
	assume	cs:_TEXT,ds:DGROUP,es:EGROUP,ss:DGROUP
_TEXT	ends					;
						;
_DATA	segment word public 'DATA'		;
mark	db	'o'				;
_DATA	ends					;
						;
_BSS	segment word public 'BSS'		;
_BSS	ends					;
						;
_EXTRA	segment word public			;
_EXTRA	ends					;
						;
_TEXT	segment					;
						;
extrn	DGROUP@		:word			;
extrn	_outfile	:word			;
extrn	_infname	:word			;
extrn	_outfname	:word			;
extrn	_codesize	:word			;
extrn	_crc		:word			;
extrn	_copying	:byte			;
extrn	_crcflg		:byte			;
extrn	_tstflg		:byte			;
extrn	_error		:near			;
extrn	_ftell		:near			;
extrn	_fseek		:near			;
						;
N		equ	4096			; 僶僢僼傽偺戝偒偝
F		equ	60			; 愭撉傒僶僢僼傽偺戝偒偝
THRESHOLD	equ	2			;
NIL		equ	N			; 栘偺枛抂
ROOTMK		equ	-1			;
F_OLD		equ	18			; 俴俙倰們梡偺愭撉傒
						;   僶僢僼傽偺戝偒偝
	public	_text_buf, _match_position, _match_length
	public	_rson, _lson, _dad, _root, _buf2, _buf3
	public	len				;
	public	crctbl				;
	public	extra				;
						;
_BSS			segment			;
crctbl			dw	100h dup (?)	;
extra			dw	1 dup (?)	;
_match_position		dw	1 dup (?)	;
_match_length		dw	1 dup (?)	;
len			dw	1 dup (?)	;
_buf2			db	4096 dup (?)	;
_buf3			db	4096 dup (?)	;
_rson			dw	(N + 1) dup (?)	;
_lson			dw	(N + 1) dup (?)	;
_dad			dw	(N + 1) dup (?)	;
_root			dw	(N + 1) dup (?)	;
_text_buf		db	(N + F - 1) dup (?)
_BSS			ends			;
						;
;-----------------------------------------------;
;	栘峔憿偺弶婜壔				;
;-----------------------------------------------;
public	_InitTree				;
_InitTree	proc	near			;
	push	di				;
	mov	bx, 1000h			;
	mov	ah, 48h				; get memory
	int	21h				;
	jNC $_1
		xor	ax, ax			;
		push	ax			;
		mov	ax, 15			; MEMOVRERR
		push	ax			;
		call	_error			;
$_1:
	mov	DGROUP:extra, ax		;
	cld					;
	mov	es, ax				;
	mov	ax, NIL * 2			;
	mov	cx, 8000h			;
	mov	di, 0				;
	rep	stosw				;
	mov	bx, ds				;
	mov	es, bx				;
	mov	cx, N				;
	mov	di, offset DGROUP:_dad		;
	rep	stosw				;
	pop	di				;
	ret					;
_InitTree	endp				;
						;
;-----------------------------------------------;
;       Inserting node to the tree              ;
;-----------------------------------------------;
public	_InsertNode				;
_InsertNode	proc	near			;
	push	si				;
	push	di				;
	mov	es, DGROUP:extra		;
	mov	bx, di				; di = r
	shl	bx, 1				;
        add	di, offset DGROUP:_text_buf	;
						;
	mov	ax, [di]			;
	xor	ah, [di + 2]			;
	shl	ax, 1				; si = p
	mov	si, ax				;
						;
	mov	ax, NIL * 2			;
	mov	DGROUP:_rson[bx], ax		;
	mov	DGROUP:_lson[bx], ax		;
						;
	cmp	word ptr EGROUP:[si], ax	; NIL * 2
	jne	in10				;
		mov	EGROUP:[si], bx		;
		mov	DGROUP:_dad[bx], ROOTMK	;
		mov	DGROUP:_root[bx], si	;
		jmp	in9			;
in10:						;
		mov	bp, EGROUP:[si]		;
	mov	cx, ds				;
	mov	es, cx				;
	cld					;
	inc	di				;
	mov	dx, di				;
	;$_while TRUE				;
in11:						;
		mov	di, dx			;
		mov	si, bp			;
		shr	si, 1			;
		add	si, offset DGROUP:_text_buf + 1
		mov	cx, F-1			;
		repe	cmpsb			;
		mov	si, bp			;
		je	in7			;
in0:						;
		ja	in2			;
			mov	bp, DGROUP:_rson[si]
			cmp	bp, ax		; NIL * 2
			jne	in11		;
				mov	DGROUP:_rson[si], bx
				mov	DGROUP:_dad[bx], si
				jmp	in9	;
in2:						;
			mov	bp, DGROUP:_lson[si]
			cmp	bp, ax		; NIL * 2
			jne	in11		;
				mov	DGROUP:_lson[si], bx
				mov	DGROUP:_dad[bx], si
				jmp	in9	;
	;$_enddo				;
in7:						;
	mov	di, DGROUP:_lson[si]		;
	mov	DGROUP:_dad[di], bx		;
	mov	DGROUP:_lson[bx], di		;
	mov	di, DGROUP:_rson[si]		;
	mov	DGROUP:_dad[di], bx		;
	mov	DGROUP:_rson[bx], di		;
	mov	di, DGROUP:_dad[si]		;
	mov	DGROUP:_dad[bx], di		;
						;
	mov	word ptr DGROUP:_dad[si], ax	; NIL * 2
	or di, di
	jNS $_2
						; ROOTMK
		mov	es, DGROUP:extra	;
		mov	di, DGROUP:_root[si]	;
		mov	DGROUP:_root[bx], di	;
		mov	EGROUP:[di], bx		;
		jmp	short in9		;
$_2:
	cmp DGROUP:_rson[di], si
	jNE $_3
		mov	DGROUP:_rson[di], bx	;
	jmp short $_4
$_3:
		mov	DGROUP:_lson[di], bx	;
$_4:
						;
in9:						;
	pop	di				;
	pop	si				;
	ret					;
_InsertNode	endp				;
						;
;-----------------------------------------------;
;                                               ;
;-----------------------------------------------;
public	_MatchInsertNode			;
_MatchInsertNode	proc	near		;
	push	si				;
	push	di				;
	mov	es, DGROUP:extra		;
	mov	bx, di				; di = r
	shl	bx, 1				;
        add	di, offset DGROUP:_text_buf	;
	mov	ax, [di]			;
	xor	ah, [di + 2]			;
	shl	ax, 1				; si = p
	mov	si, ax				;
						;
	mov	ax, NIL * 2			;
	mov	DGROUP:_rson[bx], ax		;
	mov	DGROUP:_lson[bx], ax		;
						;
	mov	al, F - 1			;
	cmp	word ptr EGROUP:[si], NIL * 2	;
	jne	min10				;
		mov	EGROUP:[si], bx		;
		mov	DGROUP:_dad[bx], ROOTMK	;
		mov	DGROUP:_root[bx], si	;
		jmp	min9			;
min10:						;
		mov	bp, EGROUP:[si]		;
	mov	cx, ds				;
	mov	es, cx				;
	cld					;
	inc	di				;
	mov	dx, di				;
	;$_while TRUE				;
min11:						;
		mov	di, dx			;
		mov	si, bp			;
		shr	si, 1			;
		add	si, offset DGROUP:_text_buf + 1
		mov	cx, F - 1		;
		repe	cmpsb			;
		lahf				;
		je	min7			;
		cmp	cx, F - THRESHOLD - 1	;
		jge	min0			;
		cmp	cl, al			;
		jg	min0			;
		je	min5			;
			mov	al, cl		;
			sub	di, si		;
			and	di, N - 1	;
			mov	DGROUP:_match_position, di
			jmp	min0		;
min5:						;
			sub	di, si		;
			and	di, N - 1	;
			cmp	di, DGROUP:_match_position
			jge	min6		;
				mov	DGROUP:_match_position, di
min6:						;
						;
min0:						;
		mov	si, bp			;
		sahf				;
		ja	min2			;
			mov	bp, DGROUP:_rson[si]
			cmp	bp, NIL * 2	;
			jne	min11		;
				mov	DGROUP:_rson[si], bx
				mov	DGROUP:_dad[bx], si
				jmp	min9	;
min2:						;
			mov	bp, DGROUP:_lson[si]
			cmp	bp, NIL * 2	;
			jne	min11		;
				mov	DGROUP:_lson[si], bx
				mov	DGROUP:_dad[bx], si
				jmp	min9	;
	;$_enddo				;
min7:						;
	mov	al, -1				;
	sub	di, si				;
	and	di, N - 1			;
	mov	DGROUP:_match_position, di	;
						;
	mov	si, bp				;
	mov	di, DGROUP:_lson[si]		;
	mov	DGROUP:_dad[di], bx		;
	mov	DGROUP:_lson[bx], di		;
	mov	di, DGROUP:_rson[si]		;
	mov	DGROUP:_dad[di], bx		;
	mov	DGROUP:_rson[bx], di		;
	mov	di, DGROUP:_dad[si]		;
	mov	DGROUP:_dad[bx], di		;
						;
	mov	word ptr DGROUP:_dad[si], NIL * 2
	or di, di
	jNS $_5
		mov	es, DGROUP:extra	;
		mov	di, DGROUP:_root[si]	;
		mov	DGROUP:_root[bx], di	;
		mov	EGROUP:[di], bx		;
		jmp	short min9		;
$_5:
	cmp DGROUP:_rson[di], si
	jNE $_6
		mov	DGROUP:_rson[di], bx	;
	jmp short $_7
$_6:
		mov	DGROUP:_lson[di], bx	;
$_7:
						;
min9:						;
	dec	word ptr DGROUP:_match_position	;
	cbw					;
	neg	ax				;
	add	ax, F - 1			;
	mov	DGROUP:_match_length, ax	;
	pop	di				;
	pop	si				;
	ret					;
_MatchInsertNode	endp			;
						;
;-----------------------------------------------;
;       Deleting node from the tree             ;
;-----------------------------------------------;
public	_DeleteNode				;
_DeleteNode	proc	near			;
	push	si				;
	push	di				;
	mov	es, DGROUP:extra		;
						;
	mov	dx, NIL * 2			;
	shl	si, 1				;
	cmp word ptr DGROUP:_dad[si], dx
	jNE $_8
		jmp	dn9			;
$_8:
	cmp word ptr DGROUP:_rson[si], dx
	jNE $_10
		mov	di, DGROUP:_lson[si]	;
		jmp short $_9
$_10:
	cmp word ptr DGROUP:_lson[si], dx
	jNE $_11
		mov	di, DGROUP:_rson[si]	;
		jmp short $_9
$_11:
		mov	di, DGROUP:_lson[si]	;
		mov	ax, DGROUP:_rson[di]	;
		cmp ax, dx
		jE $_13
$_14:
				mov	di, ax	;
				mov	ax, DGROUP:_rson[di]
			cmp ax, dx
			jNE $_14
$_15:
			mov	ax, DGROUP:_lson[di]
			mov	bx, DGROUP:_dad[di]
			mov	cx, bx		;
			mov	DGROUP:_rson[bx], ax
			mov	bx, DGROUP:_lson[di]
			mov	DGROUP:_dad[bx], cx
			mov	ax, DGROUP:_lson[si]
			mov	DGROUP:_lson[di], ax
			mov	bx, DGROUP:_lson[si]
			mov	DGROUP:_dad[bx], di
$_13:
		mov	ax, DGROUP:_rson[si]	;
		mov	DGROUP:_rson[di], ax	;
		mov	bx, DGROUP:_rson[si]	;
		mov	DGROUP:_dad[bx], di	;
$_12:
$_9:
	mov	bx, DGROUP:_dad[si]		;
	mov	DGROUP:_dad[di], bx		;
	or bx, bx
	jNS $_16
		mov	bx, DGROUP:_root[si]	;
		mov	DGROUP:_root[di], bx	;
		mov	EGROUP:[bx], di		;
	jmp short $_17
$_16:
		cmp DGROUP:_rson[bx], si
		jNE $_18
			mov	DGROUP:_rson[bx], di
		jmp short $_19
$_18:
			mov	DGROUP:_lson[bx], di
$_19:
$_17:
	mov	DGROUP:_dad[si], dx		;
dn9:						;
	pop	di				;
	pop	si				;
	ret					;
_DeleteNode	endp				;
						;
extrn	_textsize	:word			;
						;
extrn	_infile		:word			;
extrn	_StartModel	:near			;
extrn	_EncodeChar	:near			;
extrn	_EncodePosition	:near			;
extrn	_EncodeEnd	:near			;
						;
extrn	_outfile	:word			;
extrn	_DecodeChar	:near			;
extrn	_DecodePosition	:near			;
						;
extrn	_blkcnt		:word			;
extrn	_curcnt		:word			;
extrn	_nxtcnt		:word			;
						;
;-----------------------------------------------;
;	LArc type 5 偺 buffer 弶婜壔		;
;-----------------------------------------------;
public	InitBuf					;
InitBuf	proc	near				;
	cld					;
	mov	di, ds				;
	mov	es, di				;
	mov	di, offset DGROUP:_text_buf	;
	mov	al, 0				;
	mov	bx, 13				;
$_20:
		mov	cx, bx			;
		rep	stosb			;
		inc	al			;
	jNZ $_20
$_21:
$_22:
		stosb				;
		inc	al			;
	jNZ $_22
$_23:
$_24:
		dec	al			;
		stosb				;
	jNZ $_24
$_25:
	mov	cx, 128				;
	rep	stosb				;
	mov	cx, 128				;
	mov	al, 20h				;
	rep	stosb				;
	ret					;
InitBuf	endp					;
						;
;-----------------------------------------------;
;	LZHUF 偺 encode				;
;-----------------------------------------------;
public	_Encode					;
_Encode	proc	near				;
	push	si				;
	push	di				;
	push	bp				;
	mov	ax,word ptr DGROUP:_textsize	;
	or	ax,word ptr DGROUP:_textsize + 2;
	jNZ $_26
		jmp	en05			;
$_26:
	call	near ptr _StartModel		;
	call	near ptr _InitTree		;
	call	near ptr InitBuf		;
	mov	cx, F				;
	sub	di, cx				;
en01:						;
	mov	bx, DGROUP:_infile		;
	getc_crc@				;
	or	ax, ax				;
	js	en02				;
	stosb					;
	loop	en01				;
en02:						;
	mov	ax, F				;
	sub	ax, cx				;
	mov	word ptr len, ax		;
	xor	ax, ax				;
	mov	word ptr DGROUP:_textsize, ax	;
	mov	word ptr DGROUP:_textsize + 2, ax
	mov	di, N - F			;
	mov	si, di				;
	mov	cx, F				;
$_27:
		dec	di			;
		push	cx			;
		call	_InsertNode		;
		pop	cx			;
	LOOP $_27
$_28:
	mov	di, si				;
	call	near ptr _MatchInsertNode	;
	xor	si, si				;
$_29:
		mov	bx, word ptr DGROUP:_match_length
		cmp bx, word ptr len
		jLE $_31
			mov	bx, word ptr len;
			mov	word ptr DGROUP:_match_length, bx
$_31:
		push	si			;
		push	di			;
		cmp bx, THRESHOLD
		jG $_32
			mov	word ptr DGROUP:_match_length, 1

⌨️ 快捷键说明

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