; Recherche un motif spécifié dans un tampon. En cas de discordance, ; utilise la valeur de l'octet discordant pour sauter le plus de ; correspondance possible (Boyer-Moore partiel). ; Retourne l'offset de départ de la première correspondance à rechercher, ou NULL ; si aucune correspondance n'est trouvée. ; Nécessite que le motif ne soit pas plus long que 255 octets, et qu'il y ait ; au moins une correspondance du motif dans le tampon (par exemple, une ; copie du motif devrait être placée en tant que sentinelle à la fin ; du tampon si le motif n'est pas déjà dans le tampon). ; Testé avec TASM. ; Appelable depuis C near comme suit: ; unsigned char * FindString(unsigned char * BufferPtr, ; unsigned int BufferLength, unsigned char * PatternPtr, ; unsigned int PatternLength); parms struc dw 2 dup(?) ;BP & adresse de retour empilés BufferPtr dw ? ;pointeur sur le tampon à rechercher BufferLength dw ? ;nombre d'octets dans le tampon à rechercher ;(pas employé, actuellement) PatternPtr dw ? ;pointeur sur le motif ;(le motif *DOIT* être dans le tampon) PatternLength dw ? ;longueur du motif (doit ;être <= 255) parms ends .model small .code public _FindString _FindString proc near cld push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur notre stack frame push si ;préserve les variables registre de l'appelant push di sub sp,256 ;alloue de l'espace à SkipTable ; Crée une table de distance afin de sauter lors d'une discordance ; de chaque valeur d'octet possible. ; Premièrement, initialise tous les sauts à la longueur ; du motif; distance de saut des octets qui n'apparaissent pas ; dans le motif. mov di,ds mov es,di ;ES=DS=SS mov di,sp ;pointe sur SkipBuffer mov al,byte ptr [bp+PatternLength] and al,al ;retourne immédiatement une correspondance si le motif jz InstantMatch ; à une longueur=0 mov ah,al mov cx,256/2 rep stosw mov ax,[bp+PatternLength] dec ax ;nous avons uniquement besoin que mov [bp+PatternLength],ax ; PatternLength - 1 ; Pointe sur l'octet le plus à droite de l'emplacement d'une première ; correspondance éventuelle dans le tampon. add [bp+BufferPtr],ax ; Paramètre la valeur de saut des octets qui apparaissent dans le motif ; avec la distance entre la position de l'octet à la fin du motif. mov si,[bp+PatternPtr] ;pointe sur le début du motif and ax,ax ;reste-t-il des sauts à paramètrer? jz SetSkipDone ;non mov di,sp ;pointe sur SkipBuffer sub bx,bx ;prépare l'adressage du mot de la valeur de l'octet off SetSkipLoop: mov bl,[si] ;récupère le prochain octet du motif inc si ;avance le pointeur du motif mov [di+bx],al ;paramètre la valeur de saut quand cette valeur de ;l'octet est la valeur de discordance dans le tampon dec ax jnz SetSkipLoop SetSkipDone: mov dl,[si] ;DL=l'octet le plus à droite du motif dés à présent dec si ;pointe sur le prochain octet le plus à droite du motif mov [bp+PatternPtr],si ; Search the buffer. std ;inverse REPZ CMPSB mov di,[bp+BufferPtr] ;pointe sur le premier emplacement à rechercher mov bx,sp ;pointe sur SkipTable pour XLAT SearchLoop: sub ah,ah ;utilisé pour convertir AL en un mot ; Saute jusqu'à ce qu'il y ait une correspondance avec le premier octet du motif. QuickSearchLoop: ; Voyons si nous avons une correspondance avec le premier emplacement du tampon. REPT 8 ;déroule la boucle 8 fois pour réduire les branchements mov al,[di] ;le prochain octet du tampon cmp dl,al ;correspond-il au motif? jz FullCompare ;oui, alors xlat ;non, se réfère à la table pré-calcule pour cette ;discordance add di,ax ;BufferPtr += Skip; ENDM jmp QuickSearchLoop ; Retourne un pointeur sur le début du tampon (pour un motif de longueur=0) align 2 InstantMatch: mov ax,[bp+BufferPtr] jmp short Done ; Compare l'emplacement du motif avec celui du tampon, de droite à gauche. align 2 FullCompare: mov [bp+BufferPtr],di ;sauve l'emplacement actuel dans le tampon mov cx,[bp+PatternLength] ;nombre d'octets restant à comparer jcxz Match ;termine, s'il n'y avait qu'un caractère dec di ;pointe sur le prochain octet de destination pour comparer ; ;(SI pointe sur le prochain octet le plus à droite ) repz cmpsb ;compare le reste du motif jz Match ;nous avons trouvé une correspondance ;C'est une discordance ;voyons ce que nous en apprenons. inc di ;compense le dépassement de 1 octet de REPZ CMPSB; ;pointe sur l'emplacement discordant dans le tampon ; nombre d'octets qui ont correspondu. mov si,[bp+BufferPtr] sub si,di ; Si, en nous basant sur le caractère discordant, nous ne pouvons même pas ; sauter aussi loin que de là d'où nous avons commencé cette comparaison, alors ; nous avançons simplement de 1 jusqu'à la prochaine correspondance éventuelle; ; sinon, nous sautons de la distance de saut du caractère discordant à partir du ; point de comparaison, moins la distance parcourue par la correspondance ; partielle. mov al,[di] ;récupère la valeur de l'octet discordant dans le tampon xlat ;récupère la valeur de saut de cette discordance mov cx,1 ;suppose que nous avançons juste vers la prochaine ;correspondance éventuelle sub ax,si ;le saut est-il suffisamment long? jna MoveAhead ;non, avançons de 1 par défaut mov cx,ax ;oui, c'est la distance pour sauter à partir de la ;dernière correspondance éventuelle testée MoveAhead: ; Saute et effectue la prochaine comparaison. mov di,[bp+BufferPtr] add di,cx ;BufferPtr += Skip; mov si,[bp+PatternPtr] ;pointe sur le prochain octet le plus à droite ;du motif jmp SearchLoop ; Retourne le début de la correspondance dans le tampon (BufferPtr - (PatternLength - 1)). align 2 Match: mov ax,[bp+BufferPtr] sub ax,[bp+PatternLength] Done: cld ;restaure le drapeau de direction par défaut add sp,256 ;désalloue de l'espace à SkipTable pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _FindString endp end