;Recherche dans un tampon de caractères une chaîne de texte. Utilise REPNZ SCASB ;pour rechercher dans le tampon le premier caractère de la chaîne ;puis utilise REPZ CMPS pour vérifier complètement les emplacements ;que REPNZ SCASB a identifié comme d'éventuelles correspondances. ; ;Adapté de Zen of Assembly Language, par Michael Abrash ; ;Fonctions appelables depuis C en modèle small: ; unsigned char * FindString(unsigned char * Buffer, ; unsigned int BufferLength, unsigned char * SearchString, ; unsigned int SearchStringLength); ; ; Retourne le pointeur sur la première occurrence de SearchString dans Buffer, ou ; un pointeur NULL si aucune correspondance n'a été trouvée. Buffer ne doit pas ; commencer à l'offset 0 dans le segment de données pour éviter de confondre une ; correspondance trouvée à 0 avec " aucune correspondance trouvée ". Parms struc dw 2 dup(?) ;BP empilé/adresse 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 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 chaîne ;incrementent ;les pointeurs mov si,[bp+SearchString] ;pointeur sur la chaîne à ; rechercher mov bx,[bp+SearchStringLength] ;longueur de ;la chaîne jz FindStringNotFound ;aucune correspondance si la ;chaîne a une longueur égale à 0 mov dx,[bp+BufferLength] ;longueur du tampon sub dx,bx ;différence entre la longueur du ;tampon et celle de la chaîne jc FindStringNotFound ;aucune correspondance si l ;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 ;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 lodsb ;met le premier octet de ;la chaîne à ;rechercher dans AL mov bp,si ;positionne le pointeur sur ;le second ;octet à rechercher dec bx ;pas besoin de comparer avec CMPS ;nous le faisons avec SCAS FindStringLoop: mov cx,dx ;met le reste de la longueur du ;tampon à rechercher dans CX repnz scasb ;recherche le premier octet de ; la chaîne jnz FindStringNotFound ;n'est pas trouvé, donc il ;n'y a pas de correspondance ;trouvée, donc il y a une éventuelle correspondance ;vérifions le reste push di ;mémorise l'adresse du prochain ;octet à analyser mov dx,cx ;met le reste de la longueur à ;rechercher dans le tampon mov si,bp ;pointe sur le reste de la ; chaîne à rechercher mov cx,bx ;longueur de la chaîne (minorée ; du premier octet) shr cx,1 ;convertit en mot pour ; rechercher plus vite jnc FindStringWord ;effectue la recherche du mot ;s'il n'y a pas d'octet impair cmpsb ;compare l'octet impair jnz FindStringNoMatch ;l'octet impair ne correspond ;pas donc nous n'avons pas ;trouvé la chaîne ici FindStringWord: jcxz FindStringFound ;teste si nous avons déjà ;vérifié la chaîne en entier si ;tel est le cas, il y a une ;correspondance 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 ;pointeur revient sur le prochain octet and dx,dx ;reste-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 là où la chaîne a été trouvée dec ax ;(plus tôt nous avons empilé l'adresse ;de l'octet après le début d'une ;éventuelle correspondance) 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