Lzss unité
Compresser et décompresser appareil à l'aide d'algorithme LZ77 pour
Borland () le Turbo Pascal version 7.0
l'auteur: ANDREW EIGUS
Unité LZSSUnit
{
LZSSUNIT - Compresser et décompresser appareil à l'aide d'algorithme LZ77 pour
Borland () le Turbo Pascal version 7.0.
l'Assembleur Programmateur: Andy Tam, Pascal Conversion: Douglas Webb,
Unité de Conversion et Allocation Dynamique de la Mémoire: Andrew Eigus.
le Domaine Public de la version 1.02, dernière modification le 30.11.94.
plateformes Cibles: DOS, DPMI, Windows.
Écrit par Andrew Eigus (aka: M. Octet) de:
Fidonet: 2:5100/33,
Internet: [email protected], [email protected].
}
interface
{#Z }
{ Cette unité est prête pour une utilisation avec Dj. Murdoch & #39 s ScanHelp utilitaire qui
va faire un Borland .TPH fichier. }
{#Z-}
const
LZRWBufSize = 8192 { taille de tampon de Lecture }
{#Z }
N = 4096 { Plus N -> une Meilleure compression sur les gros fichiers. }
F = 18
Seuil = 2
Nul = N * 2
InBufPtr : word = LZRWBufSize
InBufSize : word = LZRWBufSize
OutBufPtr : word = 0
{#Z-}
type
{#X TWriteProc}{#X LZSquash}{#X LZUnsquash}
TReadProc = function(var ReadBuf var NumRead : word) : mot
{ C'est la déclaration de personnalisé la fonction de lecture. Il faut lire
#LZRWBufSize# octets de ReadBuf. La valeur de retour est ignorée. }
{#X TReadProc}{#X LZSquash}{#X LZUnsquash}
TWriteProc = function(var WriteBuf Count : mot var NumWritten : word) :
mot { C'est la déclaration de personnalisé la fonction d'écriture. Il devrait écrire
Count octets dans WriteBuf et de retourner le nombre d'octets écrits
en NumWritten variable. La valeur de retour est ignorée. }
{#Z }
PLZRWBuffer = ^TLZRWBuffer
TLZRWBuffer = array[0..LZRWBufSize - 1] of Byte { tampons de fichier }
PLZTextBuf = ^TLZTextBuf
TLZTextBuf = array[0..N F - 2] of Byte
PLeftMomTree = ^TLeftMomTree
TLeftMomTree = array[0..N] de Mot
PRightTree = ^TRightTree
TRightTree = array[0..N 256] de Word
const
LZSSMemRequired = SizeOf(TLZRWBuffer) * 2
SizeOf(TLZTextBuf) SizeOf(TLeftMomTree) * 2 SizeOf(TRightTree)
{#Z-}
la fonction LZInit : boolean
{ Cette fonction doit être appelée avant toute autre routines de compression
à partir de cette unité - il alloue de la mémoire et initialise tous les internes
les variables requises par la compression des procédures. Si l'allocation échoue,
LZInit renvoie la valeur False, ce qui signifie qu'il n'y a & #39 t de suffisamment de mémoire pour
la compression ou la décompression de processus. Elle retourne True si l'initialisation
a été couronnée de succès. }
{#X LZDone}{#X LZSquash}{#X LZUnsquash}
procédure LZSquash(ReadProc : TReadProc WriteProc : TWriteProc)
{ Cette procédure est utilisée pour la compression. ReadProc spécifie personnalisée
fonction de lecture qui lit les données, et WriteProc spécifie écriture personnalisée
fonction qui écrit les données compressées. }
{#X LZUnsquash}{#X LZInit}{#X LZDone}
procédure LZUnSquash(ReadProc : TReadProc WriteProc : TWriteProc)
{ Cette procédure est utilisée pour la décompression. ReadProc spécifie personnalisée
fonction de lecture qui lit des données compressées, et WriteProc spécifie
coutume d'écrire la fonction qui écrit décompressé de données. }
{#X LZSquash}{#X LZInit}{#X LZDone}
procédure LZDone
{ Cette procédure doit être appelée après que vous avez terminé de compression ou
décompression. Il libère (libère) toute la mémoire allouée par LZInit.
Remarque: Vous devez toujours appeler LZDone après vous avez terminé d'utiliser la compression
routines à partir de cet appareil. }
{#X LZInit}{#X LZSquash}{#X LZUnsquash}
la mise en œuvre
var
Hauteur, MatchPos, MatchLen, LastLen : mot
TextBufP : PLZTextBuf
LeftP, MomP : PLeftMomTree
RightP : PRightTree
CodeBuf : array[0..16] of Byte
LZReadProc : TReadProc
LZWriteProc : TWriteProc
InBufP, OutBufP : PLZRWBuffer
Bytes : mot
Initialisé : boolean
la Fonction LZSS_Read : mot { Retourne # d'octets lus }
Begin
LZReadProc(InBufP^, Octets)
LZSS_Read := Octets
End { LZSS_Read }
la Fonction LZSS_Write : mot { Retourne # d'octets écrits }
Begin
LZWriteProc(OutBufP^, OutBufPtr, Octets)
LZSS_Write := Octets
End { LZSS_Write }
Procédure Getc assembleur
Asm
{
getc : retour d'un personnage à partir de la mémoire tampon
de RETOUR : AL = entrée char
Porter ensemble lorsque EOF
}
push bx
mov bx, inBufPtr
cmp bx, inBufSize
jb @getc1
push cx
push dx
push-di
push-si
appel LZSS_Read
pop-si
pop di
pop dx
pop cx
mov inBufSize, ax
ou à la hache, ax
jz @getc2 { EOF }
xor bx, bx
@getc1:
PUSH-DI
LES DI,[InBufP]
MOV AL,BYTE PTR [ES:DI BX]
POP DI
inc bx
mov inBufPtr, bx
pop bx
clc { effacer le drapeau de portage }
jmp @end
@getc2: pop bx
stc { set portent à indiquer EOF }
@fin:
End { Getc }
Procédure Putc assembleur
{
putc : revêtir un caractère dans le tampon de sortie
Entrée : AL = sortie char
}
Asm
push bx
mov bx, outBufPtr
PUSH-DI
LES DI,[OutBufP]
MOV BYTE PTR [ES:DI BX],AL
POP DI
inc bx
cmp bx, LZRWBufSize
jb @putc1
mov OutBufPtr,LZRWBufSize { Juste pour la chasse d'eau fonctionne. }
push cx
push dx
push-di
push-si
appel LZSS_Write
pop-si
pop di
pop dx
pop cx
xor bx, bx
@putc1: mov outBufPtr, bx
pop bx
End { Putc }
Procédure InitTree assembleur
{
initTree : initialisation de tous les arbres binaires. Il y a 256 BST & #39 s,
pour toutes les chaînes commencé avec un caractère particulier. L'
parent est l'arbre K est le nœud N K 1 et il n'a qu'un
droit de l'enfant
}
Asm
cld
push ds
pop-es
LES DI,[RightP]
{ mov di,décalage à droite}
ajouter des di, (N 1) * 2
mov cx, 256
mov ax, NUL
rep stosw
LES DI,[MomP]
{ mov di, le décalage maman}
mov cx, N
rep stosw
End { InitTree }
Procédure s'écartent de l'assembleur
{
splay : utilisation splay tree opérations de déplacer le nœud à l' & #39 haut & #39
arbre. Notez qu'il ne sera pas réelle devenir la racine de l'arbre
parce que la racine de chaque arbre est un nœud spécial. Au lieu de cela, il
va devenir le droit de l'enfant de ce nœud spécial.
ENTRÉE : di = le nœud de rotation
}
Asm
@Splay1:
PUSH BX
LES BX,[MomP]
MOV SI,[ES:BX DI]
POP BX
{ mov si, [Offset Maman di]}
cmp si, NUL { exit si son parent est une spéciale
node } ja @Splay4
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV BX,[ES:DI]
{ mov bx, [Offset Maman si]}
POP DI
cmp bx, NUL { vérifier si son grand-père est spéciale
} jbe @Splay5 { si non, alors skip }
PUSH BX
LES BX,[LeftP]
CMP DI,[ES:BX SI]
POP BX
{ cmp di, [Décalage à Gauche si]} { est le nœud actuel est un
à gauche de l'enfant ? } jne @Splay2
PUSH BX
LES BX,[RightP]
MOV DX,[ES:BX DI]
{ mov dx, [Offset Droit di]} { effectuer une gauche zig
fonctionnement } LES BX,[LeftP]
MOV [ES:BX SI],DX
{ mov [Décalage à Gauche si], dx}
LES BX,[RightP]
MOV [ES:BX DI],SI
POP BX
{ mov [Offset Droit di], tr}
jmp @Splay3
@Splay2:
PUSH BX
LES BX,[LeftP]
MOV DX,[ES:BX DI]
{ mov dx, [Décalage à Gauche di]} { droite de zig }
LES BX,[RightP]
MOV [ES:BX SI],DX
{ mov [Offset Droit si], dx}
LES BX,[LeftP]
MOV [ES:BX DI],SI
POP BX
{ mov [Décalage à Gauche di], tr}
@Splay3:
PUSH-SI
LES SI,[RightP]
MOV [ES:SI BX],DI
POP-SI
{ mov [Offset Droit bx], di}
xchg bx dx
PUSH AX
MOV AX,BX
LES BX,[MomP]
ADD BX,AX
MOV [ES:BX],SI
LES BX,[MomP]
MOV [ES:BX SI],DI
LES BX,[MomP]
MOV [ES:BX DI],DX
MOV BX,AX
POP AX
{ mov [Offset Maman bx], si
mov [Offset Maman si], di
mov [Offset Maman di], dx}
@Splay4: jmp @end
@Splay5:
PUSH-DI
LES DI,[MomP]
MOV CX,[ES:DI BX]
POP DI
{ mov cx, [Offset Maman bx]}
PUSH BX
LES BX,[LeftP]
CMP DI,[ES:BX SI]
POP BX
{ cmp di, [Décalage à Gauche si]}
jne @Splay7
PUSH-DI
LES DI,[LeftP]
CMP SI,[ES:DI BX]
POP DI
{ cmp si, [Décalage à Gauche bx]}
jne @Splay6
PUSH AX
MOV AX,DI
LES DI,[RightP]
AJOUTER des DI,SI
MOV DX,[ES:DI]
{ mov dx, [Offset Droit si] } { effectuer une gauche zig-zig
fonctionnement } LES DI,[LeftP]
MOV [ES:DI BX],DX
{ mov [Décalage à Gauche bx], dx}
xchg bx, dx
LES DI,[MomP]
MOV [ES:DI BX],DX
{ mov [Offset Maman bx], dx}
LES DI,[RightP]
AJOUTER des DI,AX
MOV BX,[ES:DI]
{ mov bx, [Offset Droit di]}
LES DI,[LeftP]
AJOUTER des DI,SI
MOV [ES:DI],BX
LES DI,[MomP]
MOV [ES:DI BX],SI
{ mov [Décalage à Gauche si], bx
mov [Offset Maman bx], tr}
mov bx, dx
LES DI,[RightP]
AJOUTER des DI,SI
MOV [ES:DI],BX
LES DI,[RightP]
AJOUTER des DI,AX
MOV [ES:DI],SI
{ mov [Offset Droit si], bx
mov [Offset Droit di], tr}
LES DI,[MomP]
MOV [ES:DI BX],SI
LES DI,[MomP]
AJOUTER des DI,SI
STOSW
MOV DI,AX
POP AX
{ mov [Offset Maman bx], si
mov [Offset Maman si], di}
jmp @Splay9
@Splay6:
PUSH AX
MOV AX,SI
LES SI,[LeftP]
AJOUTER SI,DI
MOV DX,[ES:SI]
{ mov dx, [Décalage à Gauche di]} { effectuer une gauche en zigzag
fonctionnement } LES SI,[RightP]
MOV [ES:SI BX],DX
{ mov [Offset Droit bx], dx}
xchg bx dx
LES SI,[MomP]
MOV [ES:SI BX],DX
{ mov [Offset Maman bx], dx}
LES SI,[RightP]
AJOUTER SI,DI
MOV BX,[ES:SI]
{ mov bx, [Offset Droit di]}
LES SI,[LeftP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Décalage à Gauche si], bx}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
mov bx, dx
LES SI,[LeftP]
AJOUTER SI,DI
MOV [ES:SI],BX
{ mov [Décalage à Gauche di], bx}
LES SI,[RightP]
AJOUTER SI,DI
MOV [ES:SI],AX
{ mov [Offset Droit di], tr}
LES SI,[MomP]
AJOUTER SI,AX
MOV [ES:SI],DI
{ mov [Offset Maman si], di}
LES SI,[MomP]
MOV [ES:SI BX],DI
MOV ES,AX
POP AX
{ mov [Offset Maman bx], di}
jmp @Splay9
@Splay7:
PUSH-DI
LES DI,[RightP]
CMP SI,[ES:DI BX]
POP DI
{ cmp si, [Offset Droit bx]}
jne @Splay8
PUSH AX
MOV AX,SI
LES SI,[LeftP]
AJOUTER SI,AX
MOV DX,[ES:SI]
{ mov dx, [Décalage à Gauche si]} { droite de zig-zig
} LES SI,[RightP]
MOV [ES:SI BX],DX
{ mov [Offset Droit bx], dx}
xchg bx dx
LES SI,[MomP]
MOV [ES:SI BX],DX
{ mov [Offset Maman bx], dx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV BX,[ES:SI]
{ mov bx, [Offset Gauche di]}
LES SI,[RightP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Offset Droit si], bx}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
mov bx, dx
LES SI,[LeftP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Décalage à Gauche si], bx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV [ES:SI],AX
{ mov [Décalage à Gauche di], tr}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
LES SI,[MomP]
AJOUTER SI,AX
MOV [ES:SI],DI
{ mov [Offset Maman si], di}
MOV ES,AX
POP AX
jmp @Splay9
@Splay8:
PUSH AX
MOV AX,SI
LES SI,[RightP]
AJOUTER SI,DI
MOV DX,[ES:SI]
{ mov dx, [Offset Droit di]} { droite de zigzag
} LES SI,[LeftP]
MOV [ES:SI BX],DX
{ mov [Décalage à Gauche bx]dx}
xchg bx dx
LES SI,[MomP]
MOV [ES:SI BX],DX
{ mov [Offset Maman bx], dx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV BX,[ES:SI]
{ mov bx, [Décalage à Gauche di]}
LES SI,[RightP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Offset Droit si], bx}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
mov bx, dx
LES SI,[RightP]
AJOUTER SI,DI
MOV [ES:SI],BX
{ mov [Offset Droit di], bx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV [ES:SI],AX
{ mov [Décalage à Gauche di], tr}
LES SI,[MomP]
AJOUTER SI,AX
MOV [ES:SI],DI
LES SI,[MomP]
MOV [ES:SI BX],DI
{ mov [Offset Maman si], di
mov [Offset Maman bx], di}
MOV ES,AX
POP AX
@Splay9: mov si, si cx
cmp si, NUL
ja @Splay10
PUSH-DI
LES DI,[LeftP]
AJOUTER des DI,SI
CMP BX,[ES:DI]
POP DI
{ cmp bx, [Décalage à Gauche si]}
jne @Splay10
PUSH BX
LES BX,[LeftP]
MOV [ES:BX SI],DI
POP BX
{ mov [Décalage à Gauche si], di}
jmp @Splay11
@Splay10:
PUSH BX
LES BX,[RightP]
MOV [ES:BX SI],DI
POP BX
{ mov [Offset Droit si], di}
@Splay11:
PUSH BX
LES BX,[MomP]
MOV [ES:BX DI],SI
POP BX
{ mov [Offset Maman di], tr}
jmp @Splay1
@fin:
End { SPlay }
Procédure InsertNode assembleur
{
insertNode : insérez le nouveau nœud de l'arbre correspondant. Notez que le
position d'une chaîne dans la mémoire tampon a également servi en tant que le nœud
.
ENTRÉE : di = position dans la mémoire tampon
}
Asm
push-si
push dx
push cx
push bx
mov dx, 1
xor ax, ax
mov matchLen, ax
mov hauteur, ax
LES SI,[TextBufP]
AJOUTER SI,DI
MOV AL,BYTE PTR [ES:SI]
{ mov al, byte ptr [Offset TextBuf di]}
shl di, 1
add ax, N 1
shl ax, 1
mov es, ax
mov ax, NUL
PUSH BX
LES BX,[RightP]
MOV WORD PTR [ES:BX DI],AX
{ mov word ptr [Offset Droit di], ax}
LES BX,[LeftP]
MOV WORD PTR [ES:BX DI],AX
POP BX
{ mov word ptr [Décalage à Gauche di], ax}
@Ins1:inc hauteur
cmp dx, 0
jl @Ins3
PUSH-DI
LES DI,[RightP]
AJOUTER des DI,SI
MOV AX,WORD PTR [ES:DI]
POP DI
{ mov ax, word ptr [Offset Droit si]}
cmp ax, NUL
je @Ins2
mov si, ax
jmp @Ins5
@Ins2:
PUSH BX
LES BX,[RightP]
MOV WORD PTR [ES:BX SI],DI
{ mov word ptr [Décalage à Droite si], di}
LES BX,[MomP]
MOV WORD PTR [ES:BX DI],SI
POP BX
{ mov word ptr [Offset Maman di], tr}
jmp @Ins11
@Ins3:
PUSH BX
LES BX,[LeftP]
ADD BX,SI
MOV AX,WORD PTR [ES:BX]
POP BX
{ mov ax, word ptr [Décalage à Gauche si]}
cmp ax, NUL
je @Ins4
mov es, ax
jmp @Ins5
@Ins4:
PUSH BX
LES BX,[LeftP]
ADD BX,SI
MOV WORD PTR [ES:BX],DI
{ mov word ptr [Décalage à Gauche si], di}
LES BX,[MomP]
ADD BX,DI
MOV WORD PTR [ES:BX],SI
POP BX
{ mov word ptr [Offset Maman di], tr}
jmp @Ins11
@Ins5: mov bx, 1
shr si, 1
shr di, 1
xor ch, ch
xor dh, dh
@Ins6:
PUSH-SI
LES SI,[TextBufP]
AJOUTER SI,DI
MOV DL,BYTE PTR [ES:SI BX]
POP-SI
PUSH-DI
LES DI,[TextBufP]
AJOUTER des DI,SI
MOV CL,BYTE PTR [ES:DI BX]
POP DI
{ mov dl, byte ptr [Offset Textbuf di bx]
mov cl, byte ptr [Offset TextBuf si bx]}
sous dx, cx
jnz @Ins7
inc bx
cmp bx, F
jb @Ins6
@Ins7: shl si, 1
shl di, 1
cmp bx, matchLen
jbe @Ins1
mov ax, si
shr ax, 1
mov matchPos, ax
mov matchLen, bx
cmp bx, F
jb @Ins1
@Ins8:
PUSH CX
LES BX,[MomP]
MOV AX,WORD PTR [ES:BX SI]
{ mov ax, word ptr [Offset Maman si]}
LES BX,[MomP]
MOV WORD PTR [ES:BX DI],AX
{ mov word ptr [Offset Maman di], ax}
LES BX,[LeftP]
MOV CX,WORD PTR [ES:BX SI]
{ mov bx, word ptr [Décalage à Gauche si]}
LES BX,[LeftP]
MOV WORD PTR [ES:BX DI],CX
{ mov word ptr [Décalage à Gauche di], bx}
LES BX,[MomP]
ADD BX,CX
MOV WORD PTR [ES:BX],DI
{ mov word ptr [Offset Maman bx], di}
LES BX,[RightP]
MOV CX,WORD PTR [ES:BX SI]
{ mov bx, word ptr [Offset Droit si]}
LES BX,[RightP]
MOV WORD PTR [ES:BX DI],CX
{ mov word ptr [Offset Droit di], bx}
LES BX,[MomP]
ADD BX,CX
MOV WORD PTR [ES:BX],DI
{ mov word ptr [Offset Maman bx], di}
LES BX,[MomP]
MOV CX,WORD PTR [ES:BX SI]
{ mov bx, word ptr [Offset Maman si]}
MOV BX,CX
POP CX
PUSH-DI
LES DI,[RightP]
CMP SI,WORD PTR [ES:DI BX]
POP DI
{ cmp si, word ptr [Offset Droit bx]}
jne @Ins9
PUSH-SI
LES SI,[RightP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Offset Droit bx], di}
jmp @Ins10
@Ins9:
PUSH-SI
LES SI,[LeftP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Décalage à Gauche bx], di}
@Ins10:
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV WORD PTR [ES:DI],NUL
POP DI
{ mov word ptr [Offset Maman si], NUL}
@Ins11: cmp hauteur, 30
jb @Ins12
appel Splay
@Ins12: pop bx
pop cx
pop dx
pop-si
shr di, 1
End { InsertNode }
Procédure DeleteNode assembleur
{
deleteNode : supprimer le noeud de l'arbre
ENTRÉE : SI = position dans la mémoire tampon
}
Asm
push-di
push bx
shl si, 1
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
CMP WORD PTR [ES:DI],NUL
POP DI
{ cmp word ptr [Offset Maman si], NUL} { si elle n'a pas de
parent alors exit } ej @del7
PUSH-DI
LES DI,[RightP]
AJOUTER des DI,SI
CMP WORD PTR [ES:DI],NUL
POP DI
{ cmp word ptr [Décalage à Droite si], NUL} { a-t-elle
droit de l'enfant ? } je @del8
PUSH BX
LES BX,[LeftP]
MOV DI,WORD PTR [ES:BX SI]
POP BX
{ mov di, word ptr [Décalage à Gauche si] } { a-t-elle à gauche
enfant ? } cmp di, NUL
je @del9
PUSH-SI
LES SI,[RightP]
AJOUTER SI,DI
MOV AX,WORD PTR [ES:SI]
POP-SI
{ mov ax, word ptr [Offset Droit di]} { a-t-elle
le droit à un petit-enfant ? } cmp ax, NUL
je @del2 { si non, puis cliquez sur skip }
@del1: mov di, ax { trouver la plus à droite
nœud } PUSH SI
LES SI,[RightP]
AJOUTER SI,DI
MOV AX,WORD PTR [ES:SI]
POP-SI
{ mov ax, word ptr [Offset Droit di] } { droite
sous-arbre } cmp ax, NUL
jne @del1
PUSH CX
MOV CX,SI
LES SI,[MomP]
AJOUTER SI,DI
MOV BX,WORD PTR [ES:SI]
{ mov bx, word ptr [Offset Maman di] } { déplacer ce nœud
la racine de } LES SI,[LeftP]
AJOUTER SI,DI
MOV AX,WORD PTR [ES:SI]
{ mov ax, word ptr [Décalage à Gauche di]} { le sous-arbre }
LES SI,[RightP]
MOV WORD PTR [ES:SI BX],AX
{ mov word ptr [Offset Droit bx], ax}
xchg ax, bx
LES SI,[MomP]
MOV WORD PTR [ES:SI BX],AX
{ mov word ptr [Offset Maman bx], ax}
LES SI,[LeftP]
AJOUTER SI,SI CX
MOV BX,WORD PTR [ES:SI]
{ mov bx, word ptr [Décalage à Gauche si]}
LES SI,[LeftP]
AJOUTER SI,DI
MOV WORD PTR [ES:SI],BX
{ mov word ptr [Décalage à Gauche di], bx}
LES SI,[MomP]
MOV WORD PTR [ES:SI BX],DI
{ mov word ptr [Offset Maman bx], di}
MOV SI,SI CX
POP CX
@del2:
PUSH CX
MOV CX,SI
LES SI,[RightP]
AJOUTER SI,SI CX
MOV BX,WORD PTR [ES:SI]
{ mov bx, word ptr [Offset Droit si]}
LES SI,[RightP]
AJOUTER SI,DI
MOV WORD PTR [ES:SI],BX
{ mov word ptr [Offset Droit di], bx}
LES SI,[MomP]
MOV WORD PTR [ES:SI BX],DI
MOV SI,SI CX
POP CX
{ mov word ptr [Offset Maman bx], di}
@del3:
PUSH CX
MOV CX,DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV BX,WORD PTR [ES:DI]
{ mov bx, word ptr [Offset Maman si]}
LES DI,[MomP]
AJOUTER des DI,CX
MOV WORD PTR [ES:DI],BX
{ mov word ptr [Offset Maman di], bx}
MOV DI,CX
POP CX
PUSH-DI
LES DI,[RightP]
CMP SI,WORD PTR [ES:DI BX]
POP DI
{ cmp si, word ptr [Offset Droit bx]}
jne @del4
PUSH-SI
LES SI,[RightP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Offset Droit bx], di}
jmp @del5
@del4:
PUSH-SI
LES SI,[LeftP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Décalage à Gauche bx], di}
@del5:
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV WORD PTR [ES:DI],NUL
POP DI
{ mov word ptr [Offset Maman si], NUL}
@del7: pop bx
pop di
shr si, 1
jmp @end
@del8:
PUSH BX
LES BX,[LeftP]
MOV DI,WORD PTR [ES:BX SI]
POP BX
{ mov di, word ptr [Décalage à Gauche si]}
jmp @del3
@del9:
PUSH BX
LES BX,[RightP]
MOV DI,WORD PTR [ES:BX SI]
POP BX
{ mov di, word ptr [Offset Droit si]}
jmp @del3
@fin:
End { DeleteNode }
Procédure de Coder en assembleur
Asm
appel initTree
xor bx, bx
mov [Offset CodeBuf bx], bl
mov dx, 1
mov ch, dl
xor si, si
mov di, N - F
@Encode2: appel getc
jc @Encode3
PUSH-SI
LES SI,[TextBufP]
AJOUTER SI,DI
MOV BYTE PTR [ES:SI BX],AL
POP-SI
{ mov byte ptr [Offset TextBuf di bx], al}
inc bx
cmp bx, F
jb @Encode2
@Encode3: ou bx, bx
jne @Encode4
jmp @Encode19
@Encode4: mov cl, bl
mov bx, 1
push-di
sous di, 1
@Encode5: appel InsertNode
inc bx
dec di
cmp bx, F
jbe @Encode5
pop di
appel InsertNode
@Encode6: mov ax, matchLen
cmp al, cl
jbe @Encode7
mov al, cl
mov matchLen, ax
@Encode7: cmp al, SEUIL
ja @Encode8
mov matchLen, 1
ou byte ptr codeBuf, ch
mov bx, dx
PUSH-SI
LES SI,[TextBufP]
AJOUTER SI,DI
MOV AL,BYTE PTR [ES:SI]
POP-SI
{ mov al, byte ptr [Offset TextBuf di]}
mov byte ptr [Offset CodeBuf bx], al
inc dx
jmp @Encode9
@Encode8: mov bx, dx
mov al, byte ptr matchPos
mov byte ptr [Offset Codebuf bx], al
inc bx
mov al, byte ptr (matchPos 1)
push cx
mov cl, 4
shl al, cl
pop cx
mov ah, byte ptr matchLen
sous ah, SEUIL 1
ajouter al, ah
mov byte ptr [Offset Codebuf bx], al
inc bx
mov dx, bx
@Encode9: shl ch, 1
jnz @Encode11
xor bx, bx
@Encode10: mov al, byte ptr [Offset CodeBuf bx]
appel putc
inc bx
cmp bx, dx
jb @Encode10
mov dx, 1
mov ch, dl
mov byte ptr codeBuf, dh
@Encode11: mov bx, matchLen
mov lastLen, bx
xor bx, bx
@Encode12: appel getc
{ jc @Encode14}
jc @Encode15
push ax
appel deleteNode
pop ax
PUSH-DI
LES DI,[TextBufP]
AJOUTER des DI,SI
stosb
POP-DI br /> { mov byte ptr [Offset TextBuf si], al}
cmp si, F - 1
jae @Encode13
PUSH-DI
LES DI,[TextBufP]
AJOUTER des DI,SI
MOV BYTE PTR [ES:DI N],AL
POP DI
{ mov byte ptr
Lzss unite
Lzss unite : Plusieurs milliers de conseils pour vous faciliter la vie.
Compresser et decompresser appareil a l'aide d'algorithme LZ77 pour
Borland () le Turbo Pascal version 7.0
l'auteur: ANDREW EIGUS
Unite LZSSUnit
{
LZSSUNIT - Compresser et decompresser appareil a l'aide d'algorithme LZ77 pour
Borland () le Turbo Pascal version 7.0.
l'Assembleur Programmateur: Andy Tam, Pascal Conversion: Douglas Webb,
Unite de Conversion et Allocation Dynamique de la Memoire: Andrew Eigus.
le Domaine Public de la version 1.02, derniere modification le 30.11.94.
plateformes Cibles: DOS, DPMI, Windows.
Ecrit par Andrew Eigus (aka: M. Octet) de:
Fidonet: 2:5100/33,
Internet: [email protected], [email protected].
}
interface
{#Z }
{ Cette unite est prete pour une utilisation avec Dj. Murdoch & #39 s ScanHelp utilitaire qui
va faire un Borland .TPH fichier. }
{#Z-}
const
LZRWBufSize = 8192 { taille de tampon de Lecture }
{#Z }
N = 4096 { Plus N -> une Meilleure compression sur les gros fichiers. }
F = 18
Seuil = 2
Nul = N * 2
InBufPtr : word = LZRWBufSize
InBufSize : word = LZRWBufSize
OutBufPtr : word = 0
{#Z-}
type
{#X TWriteProc}{#X LZSquash}{#X LZUnsquash}
TReadProc = function(var ReadBuf var NumRead : word) : mot
{ C'est la declaration de personnalise la fonction de lecture. Il faut lire
#LZRWBufSize# octets de ReadBuf. La valeur de retour est ignoree. }
{#X TReadProc}{#X LZSquash}{#X LZUnsquash}
TWriteProc = function(var WriteBuf Count : mot var NumWritten : word) :
mot { C'est la declaration de personnalise la fonction d'ecriture. Il devrait ecrire
Count octets dans WriteBuf et de retourner le nombre d'octets ecrits
en NumWritten variable. La valeur de retour est ignoree. }
{#Z }
PLZRWBuffer = ^TLZRWBuffer
TLZRWBuffer = array[0..LZRWBufSize - 1] of Byte { tampons de fichier }
PLZTextBuf = ^TLZTextBuf
TLZTextBuf = array[0..N F - 2] of Byte
PLeftMomTree = ^TLeftMomTree
TLeftMomTree = array[0..N] de Mot
PRightTree = ^TRightTree
TRightTree = array[0..N 256] de Word
const
LZSSMemRequired = SizeOf(TLZRWBuffer) * 2
SizeOf(TLZTextBuf) SizeOf(TLeftMomTree) * 2 SizeOf(TRightTree)
{#Z-}
la fonction LZInit : boolean
{ Cette fonction doit etre appelee avant toute autre routines de compression
a partir de cette unite - il alloue de la memoire et initialise tous les internes
les variables requises par la compression des procedures. Si l'allocation echoue,
LZInit renvoie la valeur False, ce qui signifie qu'il n'y a & #39 t de suffisamment de memoire pour
la compression ou la decompression de processus. Elle retourne True si l'initialisation
a ete couronnee de succes. }
{#X LZDone}{#X LZSquash}{#X LZUnsquash}
procedure LZSquash(ReadProc : TReadProc WriteProc : TWriteProc)
{ Cette procedure est utilisee pour la compression. ReadProc specifie personnalisee
fonction de lecture qui lit les donnees, et WriteProc specifie ecriture personnalisee
fonction qui ecrit les donnees compressees. }
{#X LZUnsquash}{#X LZInit}{#X LZDone}
procedure LZUnSquash(ReadProc : TReadProc WriteProc : TWriteProc)
{ Cette procedure est utilisee pour la decompression. ReadProc specifie personnalisee
fonction de lecture qui lit des donnees compressees, et WriteProc specifie
coutume d'ecrire la fonction qui ecrit decompresse de donnees. }
{#X LZSquash}{#X LZInit}{#X LZDone}
procedure LZDone
{ Cette procedure doit etre appelee apres que vous avez termine de compression ou
decompression. Il libere (libere) toute la memoire allouee par LZInit.
Remarque: Vous devez toujours appeler LZDone apres vous avez termine d'utiliser la compression
routines a partir de cet appareil. }
{#X LZInit}{#X LZSquash}{#X LZUnsquash}
la mise en œuvre
var
Hauteur, MatchPos, MatchLen, LastLen : mot
TextBufP : PLZTextBuf
LeftP, MomP : PLeftMomTree
RightP : PRightTree
CodeBuf : array[0..16] of Byte
LZReadProc : TReadProc
LZWriteProc : TWriteProc
InBufP, OutBufP : PLZRWBuffer
Bytes : mot
Initialise : boolean
la Fonction LZSS_Read : mot { Retourne # d'octets lus }
Begin
LZReadProc(InBufP^, Octets)
LZSS_Read := Octets
End { LZSS_Read }
la Fonction LZSS_Write : mot { Retourne # d'octets ecrits }
Begin
LZWriteProc(OutBufP^, OutBufPtr, Octets)
LZSS_Write := Octets
End { LZSS_Write }
Procedure Getc assembleur
Asm
{
getc : retour d'un personnage a partir de la memoire tampon
de RETOUR : AL = entree char
Porter ensemble lorsque EOF
}
push bx
mov bx, inBufPtr
cmp bx, inBufSize
jb @getc1
push cx
push dx
push-di
push-si
appel LZSS_Read
pop-si
pop di
pop dx
pop cx
mov inBufSize, ax
ou a la hache, ax
jz @getc2 { EOF }
xor bx, bx
@getc1:
PUSH-DI
LES DI,[InBufP]
MOV AL,BYTE PTR [ES:DI BX]
POP DI
inc bx
mov inBufPtr, bx
pop bx
clc { effacer le drapeau de portage }
jmp @end
@getc2: pop bx
stc { set portent a indiquer EOF }
@fin:
End { Getc }
Procedure Putc assembleur
{
putc : revetir un caractere dans le tampon de sortie
Entree : AL = sortie char
}
Asm
push bx
mov bx, outBufPtr
PUSH-DI
LES DI,[OutBufP]
MOV BYTE PTR [ES:DI BX],AL
POP DI
inc bx
cmp bx, LZRWBufSize
jb @putc1
mov OutBufPtr,LZRWBufSize { Juste pour la chasse d'eau fonctionne. }
push cx
push dx
push-di
push-si
appel LZSS_Write
pop-si
pop di
pop dx
pop cx
xor bx, bx
@putc1: mov outBufPtr, bx
pop bx
End { Putc }
Procedure InitTree assembleur
{
initTree : initialisation de tous les arbres binaires. Il y a 256 BST & #39 s,
pour toutes les chaînes commence avec un caractere particulier. L'
parent est l'arbre K est le nœud N K 1 et il n'a qu'un
droit de l'enfant
}
Asm
cld
push ds
pop-es
LES DI,[RightP]
{ mov di,decalage a droite}
ajouter des di, (N 1) * 2
mov cx, 256
mov ax, NUL
rep stosw
LES DI,[MomP]
{ mov di, le decalage maman}
mov cx, N
rep stosw
End { InitTree }
Procedure s'ecartent de l'assembleur
{
splay : utilisation splay tree operations de deplacer le nœud a l' & #39 haut & #39
arbre. Notez qu'il ne sera pas reelle devenir la racine de l'arbre
parce que la racine de chaque arbre est un nœud special. Au lieu de cela, il
va devenir le droit de l'enfant de ce nœud special.
ENTREE : di = le nœud de rotation
}
Asm
@Splay1:
PUSH BX
LES BX,[MomP]
MOV SI,[ES:BX DI]
POP BX
{ mov si, [Offset Maman di]}
cmp si, NUL { exit si son parent est une speciale
node } ja @Splay4
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV BX,[ES:DI]
{ mov bx, [Offset Maman si]}
POP DI
cmp bx, NUL { verifier si son grand-pere est speciale
} jbe @Splay5 { si non, alors skip }
PUSH BX
LES BX,[LeftP]
CMP DI,[ES:BX SI]
POP BX
{ cmp di, [Decalage a Gauche si]} { est le nœud actuel est un
a gauche de l'enfant ? } jne @Splay2
PUSH BX
LES BX,[RightP]
MOV DX,[ES:BX DI]
{ mov dx, [Offset Droit di]} { effectuer une gauche zig
fonctionnement } LES BX,[LeftP]
MOV [ES:BX SI],DX
{ mov [Decalage a Gauche si], dx}
LES BX,[RightP]
MOV [ES:BX DI],SI
POP BX
{ mov [Offset Droit di], tr}
jmp @Splay3
@Splay2:
PUSH BX
LES BX,[LeftP]
MOV DX,[ES:BX DI]
{ mov dx, [Decalage a Gauche di]} { droite de zig }
LES BX,[RightP]
MOV [ES:BX SI],DX
{ mov [Offset Droit si], dx}
LES BX,[LeftP]
MOV [ES:BX DI],SI
POP BX
{ mov [Decalage a Gauche di], tr}
@Splay3:
PUSH-SI
LES SI,[RightP]
MOV [ES:SI BX],DI
POP-SI
{ mov [Offset Droit bx], di}
xchg bx dx
PUSH AX
MOV AX,BX
LES BX,[MomP]
ADD BX,AX
MOV [ES:BX],SI
LES BX,[MomP]
MOV [ES:BX SI],DI
LES BX,[MomP]
MOV [ES:BX DI],DX
MOV BX,AX
POP AX
{ mov [Offset Maman bx], si
mov [Offset Maman si], di
mov [Offset Maman di], dx}
@Splay4: jmp @end
@Splay5:
PUSH-DI
LES DI,[MomP]
MOV CX,[ES:DI BX]
POP DI
{ mov cx, [Offset Maman bx]}
PUSH BX
LES BX,[LeftP]
CMP DI,[ES:BX SI]
POP BX
{ cmp di, [Decalage a Gauche si]}
jne @Splay7
PUSH-DI
LES DI,[LeftP]
CMP SI,[ES:DI BX]
POP DI
{ cmp si, [Decalage a Gauche bx]}
jne @Splay6
PUSH AX
MOV AX,DI
LES DI,[RightP]
AJOUTER des DI,SI
MOV DX,[ES:DI]
{ mov dx, [Offset Droit si] } { effectuer une gauche zig-zig
fonctionnement } LES DI,[LeftP]
MOV [ES:DI BX],DX
{ mov [Decalage a Gauche bx], dx}
xchg bx, dx
LES DI,[MomP]
MOV [ES:DI BX],DX
{ mov [Offset Maman bx], dx}
LES DI,[RightP]
AJOUTER des DI,AX
MOV BX,[ES:DI]
{ mov bx, [Offset Droit di]}
LES DI,[LeftP]
AJOUTER des DI,SI
MOV [ES:DI],BX
LES DI,[MomP]
MOV [ES:DI BX],SI
{ mov [Decalage a Gauche si], bx
mov [Offset Maman bx], tr}
mov bx, dx
LES DI,[RightP]
AJOUTER des DI,SI
MOV [ES:DI],BX
LES DI,[RightP]
AJOUTER des DI,AX
MOV [ES:DI],SI
{ mov [Offset Droit si], bx
mov [Offset Droit di], tr}
LES DI,[MomP]
MOV [ES:DI BX],SI
LES DI,[MomP]
AJOUTER des DI,SI
STOSW
MOV DI,AX
POP AX
{ mov [Offset Maman bx], si
mov [Offset Maman si], di}
jmp @Splay9
@Splay6:
PUSH AX
MOV AX,SI
LES SI,[LeftP]
AJOUTER SI,DI
MOV DX,[ES:SI]
{ mov dx, [Decalage a Gauche di]} { effectuer une gauche en zigzag
fonctionnement } LES SI,[RightP]
MOV [ES:SI BX],DX
{ mov [Offset Droit bx], dx}
xchg bx dx
LES SI,[MomP]
MOV [ES:SI BX],DX
{ mov [Offset Maman bx], dx}
LES SI,[RightP]
AJOUTER SI,DI
MOV BX,[ES:SI]
{ mov bx, [Offset Droit di]}
LES SI,[LeftP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Decalage a Gauche si], bx}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
mov bx, dx
LES SI,[LeftP]
AJOUTER SI,DI
MOV [ES:SI],BX
{ mov [Decalage a Gauche di], bx}
LES SI,[RightP]
AJOUTER SI,DI
MOV [ES:SI],AX
{ mov [Offset Droit di], tr}
LES SI,[MomP]
AJOUTER SI,AX
MOV [ES:SI],DI
{ mov [Offset Maman si], di}
LES SI,[MomP]
MOV [ES:SI BX],DI
MOV ES,AX
POP AX
{ mov [Offset Maman bx], di}
jmp @Splay9
@Splay7:
PUSH-DI
LES DI,[RightP]
CMP SI,[ES:DI BX]
POP DI
{ cmp si, [Offset Droit bx]}
jne @Splay8
PUSH AX
MOV AX,SI
LES SI,[LeftP]
AJOUTER SI,AX
MOV DX,[ES:SI]
{ mov dx, [Decalage a Gauche si]} { droite de zig-zig
} LES SI,[RightP]
MOV [ES:SI BX],DX
{ mov [Offset Droit bx], dx}
xchg bx dx
LES SI,[MomP]
MOV [ES:SI BX],DX
{ mov [Offset Maman bx], dx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV BX,[ES:SI]
{ mov bx, [Offset Gauche di]}
LES SI,[RightP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Offset Droit si], bx}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
mov bx, dx
LES SI,[LeftP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Decalage a Gauche si], bx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV [ES:SI],AX
{ mov [Decalage a Gauche di], tr}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
LES SI,[MomP]
AJOUTER SI,AX
MOV [ES:SI],DI
{ mov [Offset Maman si], di}
MOV ES,AX
POP AX
jmp @Splay9
@Splay8:
PUSH AX
MOV AX,SI
LES SI,[RightP]
AJOUTER SI,DI
MOV DX,[ES:SI]
{ mov dx, [Offset Droit di]} { droite de zigzag
} LES SI,[LeftP]
MOV [ES:SI BX],DX
{ mov [Decalage a Gauche bx]dx}
xchg bx dx
LES SI,[MomP]
MOV [ES:SI BX],DX
{ mov [Offset Maman bx], dx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV BX,[ES:SI]
{ mov bx, [Decalage a Gauche di]}
LES SI,[RightP]
AJOUTER SI,AX
MOV [ES:SI],BX
{ mov [Offset Droit si], bx}
LES SI,[MomP]
MOV [ES:SI BX],AX
{ mov [Offset Maman bx], tr}
mov bx, dx
LES SI,[RightP]
AJOUTER SI,DI
MOV [ES:SI],BX
{ mov [Offset Droit di], bx}
LES SI,[LeftP]
AJOUTER SI,DI
MOV [ES:SI],AX
{ mov [Decalage a Gauche di], tr}
LES SI,[MomP]
AJOUTER SI,AX
MOV [ES:SI],DI
LES SI,[MomP]
MOV [ES:SI BX],DI
{ mov [Offset Maman si], di
mov [Offset Maman bx], di}
MOV ES,AX
POP AX
@Splay9: mov si, si cx
cmp si, NUL
ja @Splay10
PUSH-DI
LES DI,[LeftP]
AJOUTER des DI,SI
CMP BX,[ES:DI]
POP DI
{ cmp bx, [Decalage a Gauche si]}
jne @Splay10
PUSH BX
LES BX,[LeftP]
MOV [ES:BX SI],DI
POP BX
{ mov [Decalage a Gauche si], di}
jmp @Splay11
@Splay10:
PUSH BX
LES BX,[RightP]
MOV [ES:BX SI],DI
POP BX
{ mov [Offset Droit si], di}
@Splay11:
PUSH BX
LES BX,[MomP]
MOV [ES:BX DI],SI
POP BX
{ mov [Offset Maman di], tr}
jmp @Splay1
@fin:
End { SPlay }
Procedure InsertNode assembleur
{
insertNode : inserez le nouveau nœud de l'arbre correspondant. Notez que le
position d'une chaîne dans la memoire tampon a egalement servi en tant que le nœud
.
ENTREE : di = position dans la memoire tampon
}
Asm
push-si
push dx
push cx
push bx
mov dx, 1
xor ax, ax
mov matchLen, ax
mov hauteur, ax
LES SI,[TextBufP]
AJOUTER SI,DI
MOV AL,BYTE PTR [ES:SI]
{ mov al, byte ptr [Offset TextBuf di]}
shl di, 1
add ax, N 1
shl ax, 1
mov es, ax
mov ax, NUL
PUSH BX
LES BX,[RightP]
MOV WORD PTR [ES:BX DI],AX
{ mov word ptr [Offset Droit di], ax}
LES BX,[LeftP]
MOV WORD PTR [ES:BX DI],AX
POP BX
{ mov word ptr [Decalage a Gauche di], ax}
@Ins1:inc hauteur
cmp dx, 0
jl @Ins3
PUSH-DI
LES DI,[RightP]
AJOUTER des DI,SI
MOV AX,WORD PTR [ES:DI]
POP DI
{ mov ax, word ptr [Offset Droit si]}
cmp ax, NUL
je @Ins2
mov si, ax
jmp @Ins5
@Ins2:
PUSH BX
LES BX,[RightP]
MOV WORD PTR [ES:BX SI],DI
{ mov word ptr [Decalage a Droite si], di}
LES BX,[MomP]
MOV WORD PTR [ES:BX DI],SI
POP BX
{ mov word ptr [Offset Maman di], tr}
jmp @Ins11
@Ins3:
PUSH BX
LES BX,[LeftP]
ADD BX,SI
MOV AX,WORD PTR [ES:BX]
POP BX
{ mov ax, word ptr [Decalage a Gauche si]}
cmp ax, NUL
je @Ins4
mov es, ax
jmp @Ins5
@Ins4:
PUSH BX
LES BX,[LeftP]
ADD BX,SI
MOV WORD PTR [ES:BX],DI
{ mov word ptr [Decalage a Gauche si], di}
LES BX,[MomP]
ADD BX,DI
MOV WORD PTR [ES:BX],SI
POP BX
{ mov word ptr [Offset Maman di], tr}
jmp @Ins11
@Ins5: mov bx, 1
shr si, 1
shr di, 1
xor ch, ch
xor dh, dh
@Ins6:
PUSH-SI
LES SI,[TextBufP]
AJOUTER SI,DI
MOV DL,BYTE PTR [ES:SI BX]
POP-SI
PUSH-DI
LES DI,[TextBufP]
AJOUTER des DI,SI
MOV CL,BYTE PTR [ES:DI BX]
POP DI
{ mov dl, byte ptr [Offset Textbuf di bx]
mov cl, byte ptr [Offset TextBuf si bx]}
sous dx, cx
jnz @Ins7
inc bx
cmp bx, F
jb @Ins6
@Ins7: shl si, 1
shl di, 1
cmp bx, matchLen
jbe @Ins1
mov ax, si
shr ax, 1
mov matchPos, ax
mov matchLen, bx
cmp bx, F
jb @Ins1
@Ins8:
PUSH CX
LES BX,[MomP]
MOV AX,WORD PTR [ES:BX SI]
{ mov ax, word ptr [Offset Maman si]}
LES BX,[MomP]
MOV WORD PTR [ES:BX DI],AX
{ mov word ptr [Offset Maman di], ax}
LES BX,[LeftP]
MOV CX,WORD PTR [ES:BX SI]
{ mov bx, word ptr [Decalage a Gauche si]}
LES BX,[LeftP]
MOV WORD PTR [ES:BX DI],CX
{ mov word ptr [Decalage a Gauche di], bx}
LES BX,[MomP]
ADD BX,CX
MOV WORD PTR [ES:BX],DI
{ mov word ptr [Offset Maman bx], di}
LES BX,[RightP]
MOV CX,WORD PTR [ES:BX SI]
{ mov bx, word ptr [Offset Droit si]}
LES BX,[RightP]
MOV WORD PTR [ES:BX DI],CX
{ mov word ptr [Offset Droit di], bx}
LES BX,[MomP]
ADD BX,CX
MOV WORD PTR [ES:BX],DI
{ mov word ptr [Offset Maman bx], di}
LES BX,[MomP]
MOV CX,WORD PTR [ES:BX SI]
{ mov bx, word ptr [Offset Maman si]}
MOV BX,CX
POP CX
PUSH-DI
LES DI,[RightP]
CMP SI,WORD PTR [ES:DI BX]
POP DI
{ cmp si, word ptr [Offset Droit bx]}
jne @Ins9
PUSH-SI
LES SI,[RightP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Offset Droit bx], di}
jmp @Ins10
@Ins9:
PUSH-SI
LES SI,[LeftP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Decalage a Gauche bx], di}
@Ins10:
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV WORD PTR [ES:DI],NUL
POP DI
{ mov word ptr [Offset Maman si], NUL}
@Ins11: cmp hauteur, 30
jb @Ins12
appel Splay
@Ins12: pop bx
pop cx
pop dx
pop-si
shr di, 1
End { InsertNode }
Procedure DeleteNode assembleur
{
deleteNode : supprimer le noeud de l'arbre
ENTREE : SI = position dans la memoire tampon
}
Asm
push-di
push bx
shl si, 1
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
CMP WORD PTR [ES:DI],NUL
POP DI
{ cmp word ptr [Offset Maman si], NUL} { si elle n'a pas de
parent alors exit } ej @del7
PUSH-DI
LES DI,[RightP]
AJOUTER des DI,SI
CMP WORD PTR [ES:DI],NUL
POP DI
{ cmp word ptr [Decalage a Droite si], NUL} { a-t-elle
droit de l'enfant ? } je @del8
PUSH BX
LES BX,[LeftP]
MOV DI,WORD PTR [ES:BX SI]
POP BX
{ mov di, word ptr [Decalage a Gauche si] } { a-t-elle a gauche
enfant ? } cmp di, NUL
je @del9
PUSH-SI
LES SI,[RightP]
AJOUTER SI,DI
MOV AX,WORD PTR [ES:SI]
POP-SI
{ mov ax, word ptr [Offset Droit di]} { a-t-elle
le droit a un petit-enfant ? } cmp ax, NUL
je @del2 { si non, puis cliquez sur skip }
@del1: mov di, ax { trouver la plus a droite
nœud } PUSH SI
LES SI,[RightP]
AJOUTER SI,DI
MOV AX,WORD PTR [ES:SI]
POP-SI
{ mov ax, word ptr [Offset Droit di] } { droite
sous-arbre } cmp ax, NUL
jne @del1
PUSH CX
MOV CX,SI
LES SI,[MomP]
AJOUTER SI,DI
MOV BX,WORD PTR [ES:SI]
{ mov bx, word ptr [Offset Maman di] } { deplacer ce nœud
la racine de } LES SI,[LeftP]
AJOUTER SI,DI
MOV AX,WORD PTR [ES:SI]
{ mov ax, word ptr [Decalage a Gauche di]} { le sous-arbre }
LES SI,[RightP]
MOV WORD PTR [ES:SI BX],AX
{ mov word ptr [Offset Droit bx], ax}
xchg ax, bx
LES SI,[MomP]
MOV WORD PTR [ES:SI BX],AX
{ mov word ptr [Offset Maman bx], ax}
LES SI,[LeftP]
AJOUTER SI,SI CX
MOV BX,WORD PTR [ES:SI]
{ mov bx, word ptr [Decalage a Gauche si]}
LES SI,[LeftP]
AJOUTER SI,DI
MOV WORD PTR [ES:SI],BX
{ mov word ptr [Decalage a Gauche di], bx}
LES SI,[MomP]
MOV WORD PTR [ES:SI BX],DI
{ mov word ptr [Offset Maman bx], di}
MOV SI,SI CX
POP CX
@del2:
PUSH CX
MOV CX,SI
LES SI,[RightP]
AJOUTER SI,SI CX
MOV BX,WORD PTR [ES:SI]
{ mov bx, word ptr [Offset Droit si]}
LES SI,[RightP]
AJOUTER SI,DI
MOV WORD PTR [ES:SI],BX
{ mov word ptr [Offset Droit di], bx}
LES SI,[MomP]
MOV WORD PTR [ES:SI BX],DI
MOV SI,SI CX
POP CX
{ mov word ptr [Offset Maman bx], di}
@del3:
PUSH CX
MOV CX,DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV BX,WORD PTR [ES:DI]
{ mov bx, word ptr [Offset Maman si]}
LES DI,[MomP]
AJOUTER des DI,CX
MOV WORD PTR [ES:DI],BX
{ mov word ptr [Offset Maman di], bx}
MOV DI,CX
POP CX
PUSH-DI
LES DI,[RightP]
CMP SI,WORD PTR [ES:DI BX]
POP DI
{ cmp si, word ptr [Offset Droit bx]}
jne @del4
PUSH-SI
LES SI,[RightP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Offset Droit bx], di}
jmp @del5
@del4:
PUSH-SI
LES SI,[LeftP]
MOV WORD PTR [ES:SI BX],DI
POP-SI
{ mov word ptr [Decalage a Gauche bx], di}
@del5:
PUSH-DI
LES DI,[MomP]
AJOUTER des DI,SI
MOV WORD PTR [ES:DI],NUL
POP DI
{ mov word ptr [Offset Maman si], NUL}
@del7: pop bx
pop di
shr si, 1
jmp @end
@del8:
PUSH BX
LES BX,[LeftP]
MOV DI,WORD PTR [ES:BX SI]
POP BX
{ mov di, word ptr [Decalage a Gauche si]}
jmp @del3
@del9:
PUSH BX
LES BX,[RightP]
MOV DI,WORD PTR [ES:BX SI]
POP BX
{ mov di, word ptr [Offset Droit si]}
jmp @del3
@fin:
End { DeleteNode }
Procedure de Coder en assembleur
Asm
appel initTree
xor bx, bx
mov [Offset CodeBuf bx], bl
mov dx, 1
mov ch, dl
xor si, si
mov di, N - F
@Encode2: appel getc
jc @Encode3
PUSH-SI
LES SI,[TextBufP]
AJOUTER SI,DI
MOV BYTE PTR [ES:SI BX],AL
POP-SI
{ mov byte ptr [Offset TextBuf di bx], al}
inc bx
cmp bx, F
jb @Encode2
@Encode3: ou bx, bx
jne @Encode4
jmp @Encode19
@Encode4: mov cl, bl
mov bx, 1
push-di
sous di, 1
@Encode5: appel InsertNode
inc bx
dec di
cmp bx, F
jbe @Encode5
pop di
appel InsertNode
@Encode6: mov ax, matchLen
cmp al, cl
jbe @Encode7
mov al, cl
mov matchLen, ax
@Encode7: cmp al, SEUIL
ja @Encode8
mov matchLen, 1
ou byte ptr codeBuf, ch
mov bx, dx
PUSH-SI
LES SI,[TextBufP]
AJOUTER SI,DI
MOV AL,BYTE PTR [ES:SI]
POP-SI
{ mov al, byte ptr [Offset TextBuf di]}
mov byte ptr [Offset CodeBuf bx], al
inc dx
jmp @Encode9
@Encode8: mov bx, dx
mov al, byte ptr matchPos
mov byte ptr [Offset Codebuf bx], al
inc bx
mov al, byte ptr (matchPos 1)
push cx
mov cl, 4
shl al, cl
pop cx
mov ah, byte ptr matchLen
sous ah, SEUIL 1
ajouter al, ah
mov byte ptr [Offset Codebuf bx], al
inc bx
mov dx, bx
@Encode9: shl ch, 1
jnz @Encode11
xor bx, bx
@Encode10: mov al, byte ptr [Offset CodeBuf bx]
appel putc
inc bx
cmp bx, dx
jb @Encode10
mov dx, 1
mov ch, dl
mov byte ptr codeBuf, dh
@Encode11: mov bx, matchLen
mov lastLen, bx
xor bx, bx
@Encode12: appel getc
{ jc @Encode14}
jc @Encode15
push ax
appel deleteNode
pop ax
PUSH-DI
LES DI,[TextBufP]
AJOUTER des DI,SI
stosb
POP-DI br /> { mov byte ptr [Offset TextBuf si], al}
cmp si, F - 1
jae @Encode13
PUSH-DI
LES DI,[TextBufP]
AJOUTER des DI,SI
MOV BYTE PTR [ES:DI N],AL
POP DI
{ mov byte ptr
Lzss unité
By commentfaire
Lzss unité : Plusieurs milliers de conseils pour vous faciliter la vie.