1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
| function Filtre(Mot,Masque: string) : boolean; register
var R: array of Integer;
Bon: boolean;
Total, Etoiles : integer; //Paramètres de comparaisons
i,n,Rn : integer; //compteurs locaux
Sesi,Sedi,Secx,Sedx,
SSesi,SSedi,SSecx : integer; //Save registres
function Columbo: boolean;
asm
jmp @PeterFalk
@Sigma: {ebx pointe R} {routine de calcul des entiers de 1 à eax dans R[]}
cmp eax,0
je @finSigma
mov Secx,ecx //save ecx
mov ecx,eax //ecx := n
shl ecx,2 //ecx:=n*4
xor eax,eax //eax compteur retour
@calcul:
add eax,dword ptr[ebx]+ecx //sommation
sub ecx,4 //terminé ?
jnz @calcul
mov ecx,Secx //replace ecx
@finSigma:
ret
@Comparer: {algorithme de comparaison - ebx pointe R}
mov Sesi,esi //save pointeurs
mov Sedi,edi
mov Secx,ecx
mov Sedx,edx
mov esi,Mot //esi pointe Mot
mov eax,DWord ptr[esi-4] //génère Temp aussi longue que Mot
call System.@NewAnsiString
mov edi,eax //edi pointe Temp
mov edx,Masque //edx pointe masque
xor ecx,ecx //ecx compteur char de Temp et Mot
mov i,ecx //i=0 compteur Mask
mov n,ecx //n=0 compteur R
@Boucle:
mov eax,i
mov al,Byte ptr[edx]+eax //Mask[i] en al
@interro:
cmp al,$3F //'?' ?
jne @etoile //non
mov al,Byte ptr[esi+ecx] //oui
mov Byte ptr[edi+ecx],al //Temp:=Temp+Mot[j]
inc ecx
jmp @FinBoucle
@etoile:
cmp al,$2A //'*' ?
jne @autre //non
add n,type integer //oui
mov eax,n
mov eax,DWord ptr[ebx+eax] //Rn:= R[n]
cmp eax,0
je @FinBoucle
mov Rn,eax
@Betoile:
mov al,Byte ptr[esi+ecx]
mov Byte ptr[edi+ecx],al
inc ecx
dec Rn
jnz @BEtoile
jmp @FinBoucle
@autre:
mov Byte ptr[edi+ecx],al
inc ecx
@FinBoucle: //Vérifie que Temp = Début du Mot}
mov DWord ptr[edi-4],ecx //nouvelle longueur Temp
mov SSedi,edi //sauver pointeurs
mov SSesi,esi
mov SSecx,ecx //Length(Temp) en ecx
xor eax,eax //result:=false;
repe cmpsb
setz al
mov ecx,SSecx //replacer les pointeurs
mov edi,SSedi
mov esi,SSesi
cmp eax,0
je @finIso
inc i
mov eax,DWord ptr[edx-4]
cmp i,eax
jne @Boucle
@finiso: //compare Temp et Mot}
xor eax,eax //result := false
mov ecx,DWord ptr[edi-4] //ecx =length(Temp)
cmp ecx,DWord ptr[esi-4] //length(Temp)=length(Mot) ?
jne @fin //non
repe cmpsb //oui : comparaison byte à byte
setz al
@fin:
mov DWord ptr[edi-4],0 //Temp:=''
mov edx,Sedx
mov ecx,Secx
mov edi,Sedi
mov esi,Sesi
ret
@PeterFalk: {algorithme de traitement du tableau R[]}
mov ebx,[R] //ebx pointe R[]
cmp Etoiles,0 //Etoiles=0 ?
jne @TotalPositif //non
call @Comparer //oui
jmp @finAlgo //retour dépendant
@TotalPositif:
cmp Total,-1
jle @finfalse
xor ecx,ecx //k:=0
mov DWord ptr[ebx],ecx //R[0]:=0
@repeat:
inc ecx //inc(k)
cmp Etoiles,ecx //k=Etoiles ?
jne @else //non
mov edx,Total //oui
mov eax,ecx //eax:=k-1
dec eax
call @Sigma
sub edx,eax //edx:=Total-Sigma(k-1)
mov DWord ptr[ebx]+ecx*4,edx //R[k]:=Total-Sigma(k-1)
call @Comparer
cmp eax,0 //Comparer=false ?
jne @finAlgo //true=>fin filtre true
@while: {false => while (k>0) and (Sigma(k)>=Total) do dec(k)}
cmp ecx,1
jl @SuiteWhile
mov eax,ecx
call @sigma //eax:=Sigma(k)
cmp eax,Total
jl @SuiteWhile
dec ecx //do dec(k)
jmp @while
@SuiteWhile:
inc DWord ptr[ebx]+ecx*4 //inc(R[k]);
jmp @until
@else:
mov DWord ptr[ebx]+ecx*4,0 // R[k]:=0;
@until:
cmp DWord ptr[ebx],0 //(R[0]=0) ?
je @repeat //oui
@finfalse:
mov eax,0 //retour false
@finAlgo:
end;
begin
asm {Vérification des strings - Calculs de Etoiles et Total}
@init:
mov edx,Masque
cmp edx,0 //Masque='' ?
jne @SInit1 //non
@ExitFalse:
mov n,0 //sortie false
jmp @FinInit
@SInit1:
mov eax,Mot
cmp eax,0 //Mot='' ?
jne @SInit2 //non => suite algo
xor ecx,ecx //i:=0
@BVerif: //boucle de vérification Masque
cmp DWord ptr[edx]-4,ecx // i = length(Masque) ?
je @ExitTrue // oui, donc que des '*'
cmp Byte ptr[edx]+ecx,$2a //Masque[i]='*'?
jne @ExitFalse //non => retour false
inc ecx //inc(i)
jmp @BVerif
@ExitTrue:
mov n,1 //Sortie true
jmp @FinInit
@SInit2:
mov ecx,DWord Ptr[eax]-4 //ecx = length(Mot)
mov eax,DWord ptr[edx]-4 //eax = length(Masque)
mov Total,ecx
sub Total,eax
xor eax,eax //compteur occurences en eax
@Compte:
cmp byte ptr[edx],$2a
jne @suite
inc eax
@suite:
inc edx
dec ecx
jnz @Compte
mov Etoiles,eax
add Total,eax
mov n,2
@finInit:
end;
case n of
0: Result:=false;
1: Result:=true;
2: begin
Setlength(R,Etoiles+1);
Result:=Columbo;
SetLength(R,0);
end;
end;
end;
procedure TFormMain.Button1Click(Sender: TObject);
var Masque,Mot,mess : string; i: integer;
begin
Masque:= '*s carrées'; Mot:='Parties carrées';
Mess:='Masque : '+Masque+#10+'Mot : '+Mot+#10#10;
if Filtre(Mot,Masque) then ShowMessage(Mess+'Mot conforme au masque')
else ShowMessage(Mess+'Mot non conforme au masque');
end; |
Partager