0
Nicu Natea
#1
presupunem ca avem sir sursa: ABBABBACBAB si vrem sa verificam de cate ori apare subsirul: AB     => 3 ori





.model small
.stack 100
.data   
sirSursa       db  'ABBABBACBAB'
dimSirSursa     equ $-sirSursa
sirCautat      db  'AB'
dimSirCautat   equ $-sirCautat


loc_offsetCurent   dw  0
loc_numarPotriviri dw  0

text1 db 'Numarul de aparitii: $'

.code

; pasam prin al caracterul cautat
; pasam prin bx offsetul catre sirul sursa din segmentul curent
; pasam prin cx dimensiunea sirului
; returnam prin ax offsetul la care a fost gasit
;    caracterul sau -1 daca nu a fost gasit

; // ax cautaOffsetCaracter(al, bx, cx)
; int cautaOffsetCaracter(char carCautat, char *sir, int lungime)
; {
;    int i = 0;
;    char gasit = 0;  ; // zero flag
;
;    for (i = 0; i < lungime; ++i)
;    {
;       if (sir[i] == carCautat)
;       {
;           gasit = 1;
;           break;
;       }
;    }
;
;    if (gasit == 1)
;    {
;       return lungime - i; // ax = lungime - i
;    }
;    else
;    {
;       return -1; // ax = -1 (0xFFFF)
;    }
;     
; }
cautaOffsetCaracter proc
    push di ; salvam registrii folositi si modificati
    push cx
    push dx
    
    mov dx, cx
    mov di, bx
    
    repne scasb
    
    jz gasit_car        ; verificam daca ultima potrivire a fost ok.
    
    mov ax, 0FFFFh      ; returnam -1
    jmp sfarsit_cautare
    
  gasit_car:
    sub dx, cx          ; calculam offsetul din lugimea intiala
    dec dx              ; vrem ca offsetul sa inceapa de la 0, nu 1
    mov ax, dx          ; returnam offsetul la care a fost gasit caracterul
    
  sfarsit_cautare:
    pop dx
    pop cx
    pop di
    ret
cautaOffsetCaracter endp


; pasam prin ax sirul cautat
; pasam prin bx sirul sursa
; pasam prin cx dimensiunea sirului
; returnam prin ax dimensiunea potrivirii
;    csau -1 daca sirurile difera

; // ax verificaPotrivire(ax, bx, cx)
; int verificaPotrivire(char *sirCautat, char *sirSursa, int lungime)
verificaPotrivire proc
    push si
    push di
    push cx
    push dx
    
    mov dx, cx
    mov si, ax
    mov di, bx
    
    repe cmpsb
    
    jz potrivire
    
    mov dx, 0FFFFh
    
  potrivire:
    mov ax, dx
    pop dx
    pop cx
    pop di
    pop si
    ret
verificaPotrivire endp


; returnam prin ax numarul de ori in care sirCautat se regaseste in sirSursa
cautaNrPotriviri proc

   ; seteaza date initiale 
   ; folosim globale, desi am putea-o face si pe stiva
   mov  loc_numarPotriviri, 0   ; numar potriviri
   mov  loc_offsetCurent,   0   ; offset curent in sirSursa; initial 0
   
 reia:
   
   mov  al, sirCautat        ; cautam sir2[0] : 'A'
   mov  bx, offset sirSursa  ; cautam in sir1 : 'ABBABBABA'
   mov  cx, dimSirSursa      ; pt intreaga dimensiune a sirului : 9
   
   add  bx, loc_offsetCurent ; muta indexul in sirul sursa la offsetul curent
   sub  cx, loc_offsetCurent ; seteaza cx conform cu numarul ramas de caractere.
   
   call cautaOffsetCaracter
   
   ; verifica daca functia a returnat -1 sau un offset valid.
   cmp  ax, 0FFFFh
   jz terminat     ; daca functia a returnat -1 am terminat cautarea
   
   ; daca nu, actualizam offsetul
   add  loc_offsetCurent, ax      ; actualizeaza offsetul curent
   
   ; si verificam daca exista o potrivire incepand de la offsetul curent
   mov  ax, offset sirCautat  ; cautam sirul 2 : 'AB'
   mov  bx, offset sirSursa   ; cautam in sir1 : 'ABBABBABA'
   add  bx, loc_offsetCurent  ;      de la offsetul curent
   mov  cx, dimSirCautat      ; pt dimensiunea celui de'al doilea sir : 2
   
   call verificaPotrivire
   
   ; verifica daca sirurile sunt identice
   cmp  ax, 0FFFFh
   jnz potrivire_gasita
   ; daca nu sunt, ne mutam pur si simplu pe urmatorul caracter si reluam verificariile
   add  loc_offsetCurent, 1
   jmp reia
   
 potrivire_gasita:
   ; daca sunt identice, ne mutam dupa  potrivire
   add  loc_offsetCurent, ax
   inc  loc_numarPotriviri
   jmp  reia
   
 terminat:
   mov  ax, loc_numarPotriviri
   ret
cautaNrPotriviri endp

start:
   mov  ax, @data
   mov  ds, ax
   mov  es, ax

   ; afisare mesaj rezultat: 
   mov  ah, 9
   lea  dx, text1
   int  21h

   call cautaNrPotriviri
   
   mov  dx, ax  ; pune rezultatul cautariilor in dx; 
   add  dx, '0' ; transforma rezultatul din dx in ascii [presupunem ca e doar o valoarea intre 0 si 9]
   
   mov  ah, 2h  ; dos 21h: 'Write character to STDOUT' ; continutul lui dl
   int  21h
   
   ; procedura exit
   mov  ah, 4ch
   int  21h
   end start
   
end start
Reply



Forum Jump: