; QSCAN3.ASM ; David Stafford COMMENT $ Comment ça marche ------------ L'idée est de parcourir le tampon en chargeant chaque paire de lettres dans un mot(16bits). Le drapeau Retenu nous indique si nous sommes ou non La paire de lettre est convertie en une adresse sur 16 bits en la décalant vers la gauche d'un bit (perdant ainsi le bit de poids fort du second caractère) puis en plaçant le drapeau Retenue sur le bit de poids faible. Le bit de poids fort du registre compteur est mit à 1.Ce registre compteur est ajouté à l'octet trouvé à l'adresse mentionnée dans une grande table (64K, naturellement). A cette adresse l'octet contiendra un 1 dans le bit de poids fort si le dernier caractère de la paire de lettres est une lettre de mot(valeur alphanumérique et apostrophe inclus ). Ce qui positionne le drapeau Retenue, car le bit du poids fort du registre compteur est également à 1.Le bit de poids faible de l'octet trouvé à l'adresse indiquée sera à 1 si le second caractère de la paire de lettres précédente était une lettre de mot et que son premier caractère n'est pas une lettre de mot. Il sera également à 1 si le premier caractère de cette paire de lettre est une lettre de mot et que son second caractère n'en est pas une. Le processus est répété. Enfin, le drapeau Retenue est sauvé pour indiquer le statut final caractère/non caractère. Le registre compteur est masqué pour supprimer le bit de poids fort et le nombre de mots reste dans le registre compteur. Cela vous paraît-il compliqué? Vous avez raison! Mais c'est rapide! Le grand avantage de cette méthode est que les sauts ne sont pas requis, les opérations sont rapides, et qu'elle ne demande qu'une table. Le processus peut être répété (déroulé) plusieurs fois. QSCAN3 peut lire 256 octets sans effectuer de saut. COMMEND $ .model small .code Test1 macro x,y ;9 ou 10 octets Addr&x: mov di,[bp+y] ;3 ou 4 octets adc di,di or ax,si add al,[di] endm Test2 macro x,y ;7 ou 8 octets Addr&x: mov di,[bp+y] ;3 ou 4 octets adc di,di add ah,[di] endm Scan = 128 ;analyse 256 octets à la fois Buffer = 4 ;parms BufferLength = 6 CharFlag = 8 WordCount = 10 public _ScanBuffer _ScanBuffer proc near push bp mov bp,sp push si push di xor cx,cx mov si,[bp+Buffer] ;si = tampon du texte mov ax,[bp+BufferLength] ;dx = longueur en octets shr ax,1 ;dx = longueur en mots jnz NormalBuf OneByteBuf: mov ax,seg WordTable mov es,ax mov di,[bp+CharFlag] mov bh,[di] ;bh = ancien CharFlag mov bl,[si] ;bl = caractère add bh,'A'-1 ;change bh en caractère add bx,bx ;prépare l'index mov al,es:[bx] cbw ;récupère le bit de poids fort ; dans ah (puis bh) shr al,1 ;récupère le bit de poids faible adc cx,cx ;cx = 0 ou 1 xchg ax,bx jmp CleanUp NormalBuf: push bp ;(1) pushf ;(2) cwd ;dx = 0 mov cl,Scan div cx or dx,dx ;il reste qq chose? jz StartAtTheTop ;plus maintenant, commençons sub cx,dx sub si,cx ;ajuste le pointeur du tampon sub si,cx inc ax ;ajuste pour lecture partielle StartAtTheTop: mov bx,dx ;récupère l'index pour commencer shl bx,1 mov di,LoopEntry[bx] ;adresse dans di xchg dx,ax ;dx est le compteur de boucles xor cx,cx ;total de mots mov bx,[bp+CharFlag] mov bl,[bx] ;bl = ancien CharFlag mov bp,seg WordTable mov ds,bp mov bp,si ;parcourt le tampon avec bp mov si,8080h ;bit hi mov ax,si ;initialise le compteur de mots shr bl,1 ;retenue = ancien CharFlag jmp di align 2 Top: add bx,bx ;restaure retenue n = 0 rept Scan/2 Test1 %n,%n*2 Test2 %n+1,%n*2+2 n = n+2 endm EndCount: sbb bx,bx ;sauve retenue if Scan ge 128 ;car al+ah peut être égal à 128! or ax,si add al,ah mov ah,0 else add al,ah and ax,7fh ;masque endif add cx,ax ;met à jour le compteur de mots mov ax,si add bp,Scan*2 dec dx ;rien d'autre? jng Quit jmp Top Quit: popf ;(2) tampon pair ou impair? jnc ItsEven clc Test1 Odd,-1 sbb bx,bx ;sauve retenue shr ax,1 adc cx,0 ItsEven: push ss ;restaure ds pop ds pop bp ;(1) CleanUp: mov si,[bp+WordCount] add [si],cx adc word ptr [si+2],0 and bh,1 ;sauve uniquement le drapeau ;Retenue mov si,[bp+CharFlag] mov [si],bh pop di pop si pop bp ret _ScanBuffer endp .data Address macro X dw Addr&X endm LoopEntry label word n = Scan REPT Scan Address %n MOD Scan n = n - 1 ENDM .fardata WordTable include qscan3.inc ;construit par MAKETAB end