Assembler - Zastosowanie stosu

0

Witam.

Jako projekt z Assemblera mieliśmy za zadanie napisać program, który pobiera ciąg znaków z wejścia i wypisuje
po jednym znaku zwielokrotnionym tyle razy, ile wynosi numer linii.

Mam taki programik:
http://4programmers.net/Pastebin/6112

Lecz nie mam w nim zastosowanego stosu.
Ktoś mógłby pomóc bo jakoś nie potrafię tego ogarnąć.

1

Zgadza się, stosu nie ma w nim zastosowanego. Pan Profesor może nie być zadowolony z wyniku, ale jest zastosowany stos!

org 100h

start:
        ; odłóż na stos wartość
        push       4c00h

		mov		ah, 9 ; wypisuje tekst aby podac ciag znakow
		mov		dx, podaj
		int		21h

		mov		ah, 0ah ; pobiera ciag znakow
		mov		dx, bufer
		int		21h
		
		xor		bx, bx ; ustawia gdzie jest koniec pobranego ciagu
		mov		bl, [dlugosc]
		mov		byte [tekst+bx+1], '$'
		
		call	wypisz_nl ; nowa linia
		
		mov		dx, pir ; wypisuje tekst piramida
		call	wypisz
		
		call	wypisz_nl
		
		xor		bx, bx ; zeruje bx
		
piramida:
		cmp		bl, byte [dlugosc] ; jezeli bl == dlugosc ciagu to koniec
		jz		koniec
		
		cmp		cl, 0 ; jesli 0 to bez spacji
		jz		bez_spacji

bez_spacji:
		mov		cl, bl ; ile razy wypisywac znak
		add		cl, 1
		
znaki:
		mov		dl, byte [tekst+bx] ; wypisywanie znaku
		call	wypisz_znak
		loop	znaki
		
		call	wypisz_nl
		
		inc		bx			; dodaje 1 do bx i leci do piramida 
		jmp		piramida
		
koniec:
		mov		dx, czyK ; wypisuje tekst czy koniec
		call	wypisz
		
		call 	wypisz_nl
		
		mov		ah, 0 ; pobiera znak 
		int		16h	
		cmp		al, 13 ; sprawdza czy znak to ENTER jesli nie to leci do start
		jnz		start

        ; pobierz z stosu numer procedury do wykonania
		pop		ax
		int		21h
			
wypisz_nl:
	    mov		dx, nowalinia
	    mov		ah, 9
	    int		21h
ret
wypisz:
	    mov		ah, 9
	    int		21h
ret
wypisz_znak:
	    mov		ah, 2
	    int		21h
ret

nowalinia	db		13, 10, '$'
bufer		db		100
dlugosc:	db		0
tekst:		times 	102	db	'$'
podaj		db		"Podaj ciag znakow: $"
pir			db		"Ciag znakow: $"
czyK		db		"Wyjsc z programu? (ENTER)$"
0

Mam do wykonania analogiczny projekt, z tym, że muszę przerobić string'a tak, żeby na wyjściu był on wypisany w odwrotnej kolejności. Bazowałam na napisanym przez akasei kodzie, ale w pewnym momencie gubię się i nie wiem co dalej. W zasadzie to do nie końca rozumiem na tyle język assemblera i przeglądałam googl'a z milion razy ale nie mogę sobie z tym poradzić. Będę wdzieczna za jakąkolwiek pomoc, wykazanie błędów itd.

https://4programmers.net/Pastebin/6286

0

@kamo kod nie ma sensu juz tutaj:

      mov di,     ah                ;przenosi wart AH do DI -rejestru wskaznikowego
      mov cx,     byte [dlugosc]    ;
      xor  ax,    ax
      
stos:
      
      mov   al,   [di]    ;przenosi do AL wart. spod adresu DS:DI

Bo na co niby wskazuje to twoje di? Nie zgubiło sie tam jakieś mov di, offset tekst albo coś podobnego?
Dalej ten skok jnz też jest bez sensu bo co prawda jest tam dec cx ale już żadnego cmp nie ma, więc na jakiej podstawie odbywa się niby ten skok?
W pętli 'zdejmij` możesz sobie do drugiego bufora przepisywać te znaki zdejmowane ze stosu, w ten sposób uzyskasz w drugim buforze znaki w odwrotnej kolejnosci.

0

Starałam się to poprawić, wprowadziłam licznik i generalnie w mojej głowie układa się to w całość ale niestety nie jest poprawne. Po skompilowaniu wyświetla się tekst Podaj ciąg znaków -> po podaniu niezliczona ilość "$" -> pytanie o zakończenie programu.

Więc podejrzewam, że winne są albo pętle ze stosem albo coś źle zadeklarowałam tylko nie wiem, 2 bufor?

org 100h

start:

      mov   ah,   9         ;wpisuje tekst zeby podac ciag znakow
      mov   dx,   podaj
      int   21h
      
      mov   ah,   0ah       ;pobiera ciag znakow
      mov   dx,   ciagznakow     ;bufor na dane
      int   21h
      
      xor   bx,   bx        ; ustawia koniec pobranego ciagu
      mov   bl,   [dlugosc]
      mov   byte [tekst+bx+1], '$'
      
      xor   bx,   bx        ;ZERUJE BX
      
      mov   di,   [tekst]
      mov cx,     [licznik]   
      xor  ax,    ax
      
bledy:
        cmp     bl, byte [dlugosc] ; jezeli bl == dlugosc ciagu to koniec
        jz      koniec
 
        cmp     cl, 0 ; jesli 0 to stos bez spacji
        jz      stos
      
stos:
      mov   al,   [di]    ;przenosi do AL wart. spod adresu DS:DI
      push  ax            ;odłóż na stos zawartosc rej ax
      inc   cx            ; zwieksz cx o 1
      dec   di            ; zmniejsz DI o 1
      jnz   stos
      
      
zdejmij:

      pop   ax            ;zdjemij argument z wierzchołka stosu i zapamietaj w ax
      mov   ax,   ciagznakow2     ;bufor na dane anagramu
      inc   di            ;zwieksz di o 1
      dec   cx            ;zmniejsz cx o 1
      jnz   zdejmij
      
znaki:
        mov     dl, byte [tekst+bx] ; wypisywanie znaku
        call    wypisz_znak
        loop    znaki
 
        call    wypisz_nl

koniec:
        mov     dx, czyK ; wypisuje tekst czy koniec
        call    wypisz
 
        call    wypisz_nl
 
        mov     ah, 0 ; pobiera znak 
        int     16h 
        cmp     al, 13 ; sprawdza czy znak to ENTER jesli nie to leci do start
        jnz     start
 
        ; pobierz z stosu numer procedury do wykonania
        pop     ax
        int     21h


wypisz_nl:
        mov     dx, nowalinia
        mov     ah, 9
        int     21h
ret
wypisz:
        mov     ah, 9
        int     21h
ret
wypisz_znak:
        mov     ah, 2
        int     21h
ret
      
nowalinia   db      13, 10, '$'
ciagznakow       db      100
ciagznakow2       db      100
dlugosc:    db      0
licznik:    dw      0
tekst:      times   102 db  '$'
podaj       db      "Podaj ciag znakow: $" 
czyK        db      "Wyjsc z programu? (ENTER)$" 
2

Pierwszy błąd już tu:

mov   di,   [tekst]

W ten sposób do di wpisujesz WARTOŚĆ znajdujacą się pod offsetem dla tekst a ty chcesz potem używać tego jako indeksu więc interesuje cię nie wartość a adres! Więc jeśli to masm to raczej mov di, offset tekst.

Dalej błąd tu:

mov   ax,   ciagznakow2     ;bufor na dane anagramu

Bo o to niby znaczy? Wpisujesz DO ax adres bufora ciagznakow2a chyba celem było wpisywać do kolejnych bajtów tego bufora dane Z ax?

Bufory tez są źle zadeklarowane bo:

ciagznakow       db      100

Deklaruje bufor o rozmiarze 1 (!) bajta i nadaje mu wartość 100, a celem było chyba utworzenie bufora 100 bajtowego?

Zalecałbym jednak wziać do ręki jakąś ksiażkę/kurs bo teraz to wygląda na jakieś permutation-driven-development i próby sklejenia czegoś na pałe.

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