10 septembrie 2010

Cautare subsir intr-un sir (asm)

date segment word public 'data'
sir1 db 'superextraconopidaexpiralidolces'
lung1 equ $-sir1 ; afla lungimea primului
CRLF equ 13,10,'$' ; linie noua
sir2 db 'conopida'
lung2 equ $-sir2
mesaj1 db 13,10,'Subsirul gasit in primul sir este ',13,10,'$'
mesaj2 db 13,10,'Subsirul nu a fost gasit!',13,10,'$'
date ends

prog segment word public 'code'
assume cs:prog, ds:date
start:
mov ax, date
mov ds, ax
; tiparire sir in care se cauta
lea dx, sir1
mov ah,9
int 21h
;tiparire subsir cautat
lea dx, sir2
mov ah,9
int 21h
; init date pt procedura de cautare a subsirului
; bx = lung1, di= sir1, cx = lung2, si = sir2
lea di, sir1
mov bx, lung1
lea si, sir2
mov cx, lung2
push ds
pop es ; ca es = ds
call cauta_subsir
; daca ZF = 1, nu a gasit
jnz afisare_subsir
lea dx, mesaj2
mov ah,9
int 21h
jmp gata
afisare_subsir:
push dx
lea dx, mesaj1
mov ah,9
int 21h
pop bx
gata:
mov ax, 4c00h
int 21h
tiparire_subsir: ; gasit
mov dl, [bx]
mov ah,2
int 21h
inc bx
loop tiparire_subsir
lea dx, CRLF
mov ah,9
int 21h
; programul propriu zis
; intrari: se cauta in (DI = offset, BX = lungime sir)
; se cauta sirul (SI, CX)
; iesiri: subsir gasit: ZF = 0, DX = offsetul sirului gasit
; subsir negasit: ZF = 1, DX = offset de inceput pt ultima cautare /sau DX = 0 daca subsir > sir
stop dw ? ; locatie oprire cautare
aici dw ? ; locatie inceput cautare
salv_si dw ?
salv_cx dw ?
cautSub proc
jcxz gata ; daca cx = 0, subsir vid
cmp bx,0
je gata ; daca bx = 0, sir vid
cmp cx, bx
jc caut ; daca cx mai mic decat bx, lungime subsir mai mica decat lungime sir
je caut ; la fel daca lungimile sunt egale
; altfel:
sub dx, dx ; facem DX = 0, ZF = 1
je gata
caut:
push bx
push di ; offsetul de unde incepe sirul
mov salv_si, si
mov salv_cx, cx ; salvez pt subsir
add bx, di ; locatia de terminare a cautarii in sir
sub bx, cx
inc bx ; locatia de inceput a ultimei cautari
mov stop, bx ; salvata la adresa stop
mov aici, di
cld
cautare:
repe cmpsb ; repeta cautarea cat timp sunt egale
je gasit ; daca ZF = 1 s-a gasit subsirul
inc aici ; altfel nu s-a gasit, se continua cu urm.locatie
mov di, aici
cmp di, stop ; s-a ajuns la sfarsit?
je ref_reg ; refacere registri
mov cx, salv_cx
mov si, salv_si
jmp cautare
gasit:
or cx, 1 ; s-a gasit, se pune ZF = 0
ref_reg:
mov dx, aici
pop di
pop bx
mov cx, salv_cx
mov si, salv_si
gata:
tip_sub
ret
cautaSub endp
prog ends

stiva segment stack 'stack'
dw 100 dup(?)
stiva ends

end start

Niciun comentariu: