[asm] szukanie podciagu w ciągu znaków

0

Mam problem z działaniem programu. Program powinien sczytywać tekst po znaku a nastepnie szukac np. słowa w zdaniu, niestety niedziała on poprawnie. Prosił bym o pomoc w odnalezieniu błedu

.MODEL tiny
.486
.stack 100h
.DATA
ciag1	db	1000 dup('$')
ciag2	db	1000 dup('$')
tekst1	db	'Wprowadz ciag:',10,13,'$'
tekst2	db	10,13,'Wprowadz szukany podciag:',10,13,'$'
nie	db	10,13,'Szukany podciag NIE istnieje!',10,13,'$'
tak	db	10,13,'Szukany podciag istnieje w ciagu!',10,13,'$'
pusty11	db	10,13,'NIE wpisano ciagu znakow!!!',10,13,'$'
pusty22	db	10,13,'NIE wpisano szukanego podciagu!!!',10,13,'$'
dlugosc	db	0

.CODE
Start:

	mov ax,@data	;wpisanie do akumulatora adresu segmentu danych czyli segment zawierajacy ciagi (.data)
	mov ds,ax	;przepisanie tego adresu do ds (data segment)
	mov es,ax	;przepisanie tego adresu do es (extra segment)

	mov dx,offset tekst1	;wyświetlenie komunikatu w1
	mov ah,09h
	int 21h
	mov si, offset ciag1
	xor cx, cx  ;zeruj CX

pobieraj1:
	mov ah,01h	;    pobranie znaku z klawiatury do rejestru al
    
	int 21h

	cmp al, 13	;jesli wciśnięto ENTER (kod znaku 13) to zakończ pobieranie
	je zakoncz_pobieranie

	cmp al, 8	;jeśli wciśnieto backspace skocz do etykiety backspace
	je backspace

	mov [si], al	;skopiuj znak do bufora
	inc cx		;zwiększ licznik wprowadzonych znaków
	inc si  
	jmp pobieraj1	;pobieraj kolejne znaki

backspace:
	cmp cx, 0	;sprawdź czy bufor nie jest pusty
	je pobieraj1

	mov dl, ' '	;wymaz znak z okna konsoli zastępują spacja
	mov ah, 2
	int 21h
	mov dl, 8	;cofnij kursor "wyświetlając" kod znaku backspace
	mov ah, 2
	int 21h
	dec cx		;zmniejsz licznik wprowadzonych znaków

	dec si
	jmp pobieraj1

zakoncz_pobieranie:
	mov [si], '$'	;zakoncz ciag znakiem $
	push cx

	mov dx,offset tekst2	;wyświetlenie komunikatu w2
	mov ah,09h
	int 21h
	mov si, offset ciag2
	
pobieraj2:
	mov ah,01h	;pobranie znaku z klawiatury do rejestru al
    
	int 21h

	cmp al, 13	;jesli wciśnięto ENTER (kod znaku 13) to zakończ pobieranie
	je zakoncz_pobieranie2

	cmp al, 8	;jeśli wciśnieto backspace skocz do etykiety backspace
	je backspace2

	mov [si], al	;skopiuj znak do bufora
	inc cx		;zwiększ licznik wprowadzonych znaków
	inc si
	jmp pobieraj2	;pobieraj kolejne znaki

backspace2:
	cmp cx, 0	;sprawdź czy bufor nie jest pusty
	je pobieraj2
	mov dl, ' '	;wymaz znak z okna konsoli zastępują spacja
	mov ah, 2
	int 21h

	mov dl, 8	;cofnij kursor "wyświetlając" kod znaku backspace
	mov ah, 2
	int 21h
	dec cx		;zmniejsz licznik wprowadzonych znaków
	dec si
	jmp pobieraj2

zakoncz_pobieranie2:
	mov [si], '$'	;zakoncz ciag znakiem $

	mov bx,offset ciag1	;wpisanie adresu ciag1 do zmiennej bx
	mov dh,cl
	mov bx,offset ciag2	;wpisanie adresu ciag2 do zmiennej bx
	pop cx
	mov dl,cl	;odczytanie długosci ciagu1


	mov dlugosc, dh	;zapisanie długości szukanego ciągu do ziennej dlugosc

	cmp dl,0	;sprawdzanie czy ciągi nie są puste
	je pusty1
	cmp dh,0

	je pusty2

	sub dl,dh	;odjęcie długości ciagu1 od ciagu2
	inc dl		;zwiekszenie obliczonej wartosci o 1
	mov cl,dl	;przepisanie obliczonej wartosci do rejestru licznikowego

	mov si,offset ciag1	;wpisanie adresu ciag1 do si
	mov di,offset ciag2	;wpisanie adresu ciag1 do di
	mov dh,[di]	;pobranie pierwszej literki z ciagu2 i zapisanie w rej. dh

	add si,cx	;dodaj do si wartosci licznika
	inc cx	;cx:=cx+1

petla:
	mov dl,[si]	;odczytaj znak z ciagu1 o adresie Si

	cmp dl,dh	;porownaj odczytany znak ciagu1 z pierwszym znakiem ciagu 2
	je sprawdz	;jesli znaki sa takie same to skocz do procedury ktora porowna aktualny adres ciagu1 z ciagiem2
dalej:
	dec si		;zmniejsz SI
	loop petla	;zmniejsz licznik i skocz do petla

	jmp nieistnieje	;jeśli skonczyła sie pętla i nie znaleziono ciągu2 to skocz do procedury wyświetlającej ko


sprawdz:
	push cx		;zapisz wartość CX i SI na stosie
	push si

	mov si,offset ciag1	;wpisanie adresu ciag1 do si
	mov di,offset ciag2	;wpisanie adresu ciag1 do di
	dec cx		;zmniejsz wartośc licznika
	add si,cx	;dodaj licznik do cx
	
	xor cx,cx	;zerowanie cx:=0
	mov cl,dlugosc	;wpisanie do licznika długości szukanego ciagu
	repe cmpsb	;instrukcja poruwnuje cx bajtów ciagow ktore zaczynaja sie od adresow si oras di
	jz istnieje	;jesli porownane ciagi sa rowne to skocz do końca programu
 
	pop si		;zdjęcie SI i CX ze stosu
	pop cx
	jmp dalej	;skok do głownej petli ktora szuka pierwszego bajtu ciagu2 w ciagu1

istnieje:
	mov dx,offset tak	;wyswietl komunikat ze znaleziono ciag
	mov ah,09h
	int 21h
	jmp koniecdos

nieistnieje:
	mov dx,offset nie	;wyswietl komunikat ze nie znaleziono ciagu
	mov ah,09h
	int 21h
	jmp koniecdos


pusty1:
	mov dx,offset pusty11   
	mov ah,09h
	int 21h
	jmp koniecdos

pusty2:
	mov dx,offset pusty22   
	mov ah,09h
	int 21h

koniecdos:

	mov ah,1	;oczekiwanie na wciśniecie klawisza
	int 21h
	mov ah,4ch	;przejdź do DOSa (koniec programu)
	int 21h

END Start
0

TDEBUG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

1 użytkowników online, w tym zalogowanych: 0, gości: 1