Occurrences()

Description

petite routine ASM (variante de pos()) qui permet de trouver le nombre d'occurrences
contenu dans un string ou un fichier sur disque.
Il est possible de scanner de gros fichier en utilisant un buffer réduit.

asm // PUSH EBP MOV EBP,ESP EBP entrée=EBP+4
{ptr(SubSTR)-1=EBP+24 ptr(Scible)=EBP+20 ptr(Depuis)=EBP+16
ptr(jusqua)=EBP+12 ptr(SommeOcc)=EBP+8
Var=EBP-4 (octets non lus)
}
SUB ESP,4 //Var
PUSH EBX //sauve contexte
PUSH ESI
PUSH EDI
//contrôle des données
MOV ESI,[EBP+24] //test SubSTR <> '' [ESI]=ptr(SubSTR)
TEST ESI,ESI
JZ @Torret
MOV EDX,[ESI-4] //length(SubSTR)
MOV EDI,[EBP+20] //test Scible <> '' [EDI]=ptr(Scible)
TEST EDI,EDI
JZ @Torret
MOV EBX,[EDI-4] // Length(Scible) dans EBX
MOV EAX,[EBP+16]
MOV EAX,[EAX] //Depuis
CMP EAX,1
JNGE @Torret // Depuis < 1
MOV ECX,EAX // Depuis -> ECX
MOV EAX,[EBP+12] //si jusqua < 1 -> arrêt
MOV EAX,[EAX] //si jusqua > Length(Scible)-> Length(Scible)
CMP EAX,1 //jusqua < 1 alors fin
JNGE @Torret //jusqua < 1
CMP EAX,EBX //jusqua,Length(Scible)
JNLE @Torret //jusqua > Length(Scible) -> arrêt
MOV EBX,EAX //jusqua < Length(Scible)->EBX
DEC EDI //Jusqua->EBX Depuis->ECX Length(SubSTR)->EDX
MOV EAX,EDI
ADD EDI,ECX //EDI -> ptr[Scible[Depuis]]
SUB EBX,EDX
SUB EBX,ECX //Jusqua-Length(SubSTR)-Depuis+2
ADD EBX,2 //Compteur de zone de scrutation
CMP EBX,1
JNGE @Torret // EBX < 1 -> arrêt
MOV ECX,EBX
MOV EAX,[EBP+24] // len(SubSTR)-1 dans EBX
MOV EBX,[EAX-4]
DEC EBX
// ECX->compteur ESI->ptr(subSTR[1]) EDI->ptr[Scible[depuis]] EBX=Len(subSTR)-1
//Depuis=ptrMEM[Scible[0]]
//------------------------ Début de la boucle de lecture------------------------
MOV [EBP-4],EBX //octets non lu maxi
MOV AH,BYTE ptr[ESI] //1) char de SubSTR dans AH
INC ESI //ESI = SubStr[2]?
@Adober: CMP AH,BYTE ptr[EDI] // SubSTR[1]=Scible[EDI]
JNZ @hentez // Chars <> au suivant
//--------trouvé ici SubSTR[1] dans Scible[EDI]
PUSH ESI
PUSH EDI
TEST EBX,EBX
JZ @kavout // car length(subSTR) = 1
MOV EDX,EBX //EDX compteur de length(subSTR)-1
@Endra: MOV AL,BYTE ptr[ESI]
INC ESI
INC EDI
CMP AL,BYTE ptr[EDI] //subSTR[EDI]=Scible[ESI]
JNZ @arsav
DEC EDX
JNZ @Endra
@kavout: PUSH EAX
MOV EAX,[EBP+8] //correspondance trouvée ici
MOV EDX,1
ADD [EAX],EDX //incremente Nb Occurrences Var
POP EAX
MOV EDX,ECX //EDX = pos compteur
SUB ECX,EBX //soustraire du compteur len subSTR
ADD ESP,4 //POP suppression EDI de la pile
CMP ECX,1 // dernier test possible trouvé
JNLE @ketPOPedi //sortie ECX > 1
DEC EDX //EDX = NB d'octets non lu
MOV [EBP-4],EDX //-> Var
MOV ECX,1 //force ECX pour sortir de la boucle
JMP @ketPOPedi //fin de trouve
@arsav: POP EDI
@ketPOPedi:POP ESI
@hentez: INC EDI
DEC ECX
JNZ @Adober
//fin de la boucle de recherche----------sortie pas tout scruté
JMP @Echu
//------------------------- Fin de la boucle de lecture------------------------
@Torret: XOR EAX,EAX //erreur data 0 octet à reporter
MOV [EBP-4],EAX
@Echu: MOV EDX,[EBP-4] //écriture dans depuis jusqua
MOV EBX,[EBP+12]
MOV EAX,[EBX] //jusqua -> EAX
SUB EAX,EDX
INC EAX //index 1° octet non lu
MOV [EBX],EDX //nb octets non lu dans jusqua
MOV EBX,[EBP+16]
MOV [EBX],EAX //index 1° octets non lu -> depuis
POP EDI //restitution contexte
POP ESI
POP EBX
MOV ESP,EBP //libération éventuelle var locale
end; //POP EBP RET

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.