; Recherche une chaîne de caractères dans un tampon de texte. Utilise REPNZ SCASB ; pour rechercher les emplacements dans le tampon qui correspond au caractère spécifié ; de la chaîne, puis utilise REPZ CMPS pour vérifier seulement les ; emplacements que REPNZ SCASB a identifié comme d'éventuelles correspondances. ; ; Appelable depuis C en modèle small comme: ; unsigned char * FindString(unsigned char * Buffer, ; unsigned int BufferLength, unsigned char * SearchString, ; unsigned int SearchStringLength, ; unsigned int ScanCharOffset); ; ; Retourne un pointeur sur la première occurrence de SearchString dans Buffer, ou ; un pointeur NULL si aucune correspondance n'est trouvée. Buffer ne doit pas ; commencer à l'offset 0 dans le segment des données pour éviter de confondre une ; correspondance à 0 avec aucune correspondance trouvée. Parms struc dw 2 dup(?) ;BP empilé/adresse de retour Buffer dw ? ;pointeur sur le tampon à rechercher BufferLength dw ? ;longueur du tampon à rechercher SearchString dw ? ;pointeur sur la chaîne à rechercher SearchStringLength dw ? ;longueur de la chaîne à rechercher ScanCharOffset dw ? ;offset dans la chaîne de caractères ;à analyser Parms ends .model small .code public _FindString _FindString proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur notre stack frame push si ;préserve les variables de registre ;de l'appelant push di cld ;les instructions de chaîne ;incrémentent les pointeurs mov si,[bp+SearchString] ;pointeur sur la chaîne à ; rechercher mov cx,[bp+SearchStringLength] ;longueur de ;la chaîne jcxz FindStringNotFound ;aucune correspondance si ;la chaîne à une longueur égale à 0 mov dx,[bp+BufferLength] ;longueur du tampon sub dx,cx ;différence entre la longueur ;du tampon et celle de la chaîne jc FindStringNotFound ;aucune correspondance si la ;chaîne est plus longue que ;le tampon inc dx ;différence entre la longueur ;du tampon et celle de la ;chaîne,plus 1 (nombre ;d'emplacements possibles du ;début de la chaîne ;à vérifier dans le tampon) mov di,ds mov es,di mov di,[bp+Buffer] ;ES:DI pointe sur le tampon à ;rechercher mov bx,[bp+ScanCharOffset] ;offset dans la chaîne ;de caractère à rechercher add di,bx ;ES:DI pointe sur le premier octet ;du tampon à parcourir mov al,[si+bx] ;met le caractère examiné dans AL inc bx ;repositionne BX à l'offset du début ;de la correspondance complète ;en comptant l'octet de bord de ;REPNZ SCASB FindStringLoop: mov cx,dx ;met le reste de la longueur du ;tampon à rechercher dans CX repnz scasb ;recherche l'octet à rechercher jnz FindStringNotFound ;il n'est pas trouvé, il n'y ;donc pas de correspondance ;trouvée nous avons donc ;trouvé la ;correspondance éventuelle ;en vérifiant le reste push di ;mémorise l'adresse du prochain ;octet à rechercher mov dx,cx ;met de coté le reste ;de la longueur ;à rechercher dans le tampon sub di,bx ;re-pointe sur le début d'une ;éventuelle correspondance ;dans le tampon mov si,[bp+SearchString] ;pointe sur le début de ;la chaîne mov cx,[bp+SearchStringLength] ;longueur de la ;chaîne shr cx,1 ;convertit en mot pour effectuer ;la recherche plus vite jnc FindStringWord ;recherche le mot si l'octet n' ;est pas impair cmpsb ;compare l'octet impair jnz FindStringNoMatch ;l'octet impair ne correspond ;pas, nous n'avons donc pas ; trouvé de correspondance ici FindStringWord: jcxz FindStringFound ;si la chaîne à seulement 1 ;octet de long, nous avons ;trouvé une correspondance repz cmpsw ;vérifie le reste de la chaîne ;mot par mot jz FindStringFound ;c'est une correspondance FindStringNoMatch: pop di ;récupère le pointeur sur le ;prochain octet à rechercher and dx,dx ;y a-t-il encore quelque chose à ;vérifier? jnz FindStringLoop ;oui, le prochain octet FindStringNotFound: sub ax,ax ;retourne un pointeur NULL ; indiquant que jmp FindStringDone ;la chaîne n'a pas été trouvée FindStringFound: pop ax ;pointe sur l'emplacement dans le ;tampon où la sub ax,bx ;chaîne a été trouvée (plus tôt nous ; avons empilé l'adresse de l'octet) FindStringDone: pop di ;restaure les variables registre de ;l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _FindString endp end