Assembler - wyświetlanie znaku w konsoli.

0

Witam, mam za zadanie napisać program w Assemblerze, którego zadaniem będzie pokazanie spadającej gwiazdki i właśnie mam w tym mały problem.
Całość kodu wygląda następująco:

.model small
.stack 24h	;stos programu

stosik SEGMENT STACK
	DB 328 DUP(?)
stosik ENDS 


dane segment

przerwa db '*',13,10,'$'
licz db 0

dane ends

kod segment
	assume cs:kod, ds:dane, ss:stosik
start:

	mov ax, seg dane
	mov ds, ax 
	mov ax, 3
	int 10h
	
	MOV AH,01h	
	MOV CH,10h	
	MOV CL,00h	
	INT 10H 
	
	mov cx, 10
	petla:
	push cx
	
	mov ah, 02h
    mov dl, 40
    mov dh, licz		
    mov bh, 0h		
    int 10h
	
	mov ah, 86h
	mov dx, 100
	mov cx, 10
	int 15h

	mov ah, 9h
	mov dx, offset przerwa
	int 21h
	
	pop cx
	INC licz
	loop petla
	
	MOV AH,01h	
	MOV CH,07h	
	MOV CL,07h	
	INT 10H 
	
	mov ah, 4ch
	int 21h
kod ends
end start
end

Mój problem polega na tym - pierwsza linijka pokazuje się symbol gwiazdki "*" a w kolejnych dziewięciu jakieś dziwne symbole, czasami jest to euro, czasami || zdarza się też literka Z - jakiś syf, po usunięciu opóźnienia

mov ah, 86h
	mov dx, 100
	mov cx, 10
	int 15h

Wyświetlają się same gwiazdki, więc doszedłem - że wina leży właśnie w tym miejscu, problem w tym, że nie rozumiem dlaczego i nie wiem jak to naprawić.

1

Nie mam pod ręką kompilatora więc nie mam jak sprawdzić ale zgaduje ze to twoje opóźnienie przestawia jakieś rejestry. Odpal to pod emu8086 i popatrz co się dzieje :-)

0

Co wg ciebie robi: int 15h (ah=86h) ?

tylko tyle potrzebujesz

...
przerwa db 8,' ',13,10,'*','$'
...
    mov ax, seg dane
    mov ds, ax 

    mov cx, 10
petla:
    push cx
 
    mov ah, 9h
    mov dx, offset przerwa
    int 21h
 
    pop cx
    loop petla

    mov ah, 4ch
    int 21h
...
0

Odpaliłem emu 8086, tyle, że podany kod nie działa, otrzymuje błąd w postaci: (20) probably no zero prefix for hex; or no 'h' suffix; or wrong addressing; or undefined var: segment dane

linia:

mov ax, seg dane

do tej pory korzystałem z TASM 1.4, więc nie do końca rozumiem o co tu chodzi :(

0

Ok, faktycznie mogłem poszukać, doszukałem się błędu. Tylko problem polega na tym, że w EMU8086, program wykonuje się poprawnie, a w TASM 1.4 - nie, w sobotę czeka mnie kolokwium, a na laboratoriach nie będę mógł korzystać z innego środowiska niż TASM.

0

Trudno powiedzieć co nie bangla. Możesz spróbować odpalić program kompilowany tym twoim tasm pod jakimś debuggerem i zobaczyć co się dzieje.

ale nie podoba mi się tu jedna rzecz. Ustawiasz ładnie ds na segment danych ale nie ustawiasz nigdzie segmentu stosu. Assume nic przecież nie ustawia. Możliwe ze po prostu nadpisujesz sobie dane tymi push...

0

Hm, jak to nie.

stosik SEGMENT STACK
	DB 328 DUP (?)
stosik ENDS 

deklaracja stosu i zarezerwowanie pamięci

kod segment
	assume cs:kod, ds:dane,  ss:stosik

bynajmniej wydaje mi się, że tak to powinno wyglądać

0

No i masz racje. Wydaje ci się...
Assume niczego (!) nie ustawia. więc póki co zadeklarowałeś stos i tyle.
Zauważ ze dla segmentu ds wykonujesz w kodzie operacje które ustawiają ds na odpowiedni segment, a dla ss już nie...

0
mov ax, stosik
	mov ss, ax

Dodałem powyższy kod, jednak nadal bez zmian.

0
  1. Pokaż pełny kod programu który odpalasz
  2. Wyjaśnij co znaczy "... a w TASM 1.4 - nie", jak to wygląda, co się dzieje.
0
.model small
.stack 24h	;stos programu

stosik SEGMENT STACK
	DB 328 DUP (?)
stosik ENDS 


dane segment

przerwa db '*',13,10,'$'
licz db 0  
opoz dw 0
                           
dane ends

kod segment

	assume cs:kod, ds:dane, ss:stosik
start:

	mov ax, seg dane
	mov ds, ax 
	mov ax, seg stosik
	mov ss, ax
	mov ax, 3
	int 10h
	
	MOV AH,01h	
	MOV CH,10h	
	MOV CL,00h	
	INT 10H 
	
	mov cx, 10
	petla:
	push cx  
	
	mov ah, 02h
    mov dl, 40
    mov dh, licz		
    mov bh, 0h		
    int 10h  
	
    ADD opoz, 2
	       
	mov ah, 9h
	mov dx, offset przerwa
	int 21h   
    
    mov ah, 86h
	mov dx, opoz
	mov cx, opoz
	int 15h    
	      
	pop cx 
	INC licz
	loop petla
	
	MOV AH,01h	
	MOV CH,07h	
	MOV CL,07h	
	INT 10H 
	
	mov ah, 4ch
	int 21h
kod ends
end start
end

"... a w TASM 1.4 - nie" - oznacza, iż w TASMie program nie wykonuje się poprawnie, a na przykład w emu8086 jest ok. Dlaczego nie wykonuje się poprawnie? Otóż, wynikiem powyższego kodu powinno być, wyświetlenie symbolu gwiazdki, z różną prędkością (najpierw szybko, następnie coraz wolniej). Odpalając program z emu - jest OK, odpalając to samo z TASMa jako wynik otrzymuje:

'*'
J
J
J
J
J
J
J
J
J

Bądź zamiast J, jakąś inną literę, bądź cyfrę, nie wiem od czego to zależy.

0

Dziwne, bynajmniej dla mnie - dla testu dorzuciłem zmienna testt i ją wyrzucam na ekran - o dziwo działa, tyle że: jeżeli usunę teraz linijkę

przerwa db '',13,10,'$'

Ro problem wraca ponownie. Znów wyskakują jakieś dziwne krzaczki zamiast gwiazdek.

.model small
.stack 24h	;stos programu

stosik SEGMENT STACK
	DB 328 DUP (?)
stosik ENDS 


dane segment

przerwa db '*',13,10,'$'
testt db '* $'
licz db 0  
opoz dw 0
                           
dane ends

kod segment

	assume cs:kod, ds:dane, ss:stosik
start:

	mov ax, seg dane
	mov ds, ax 
	mov ax, seg stosik
	mov ss, ax
	mov ax, 3
	int 10h
	
	MOV AH,01h	
	MOV CH,10h	
	MOV CL,00h	
	INT 10H 
	
	mov cx, 10
	petla:
	push cx  
	
	mov ah, 02h
    mov dl, 40
    mov dh, licz		
    mov bh, 0h		
    int 10h  
	
    ADD opoz, 2
	  
	mov ah, 9h
	mov dx, offset testt
	int 21h   
    
    mov ah, 86h
	mov dx, opoz
	mov cx, opoz
	int 15h    
	
	pop cx 
	INC licz
	loop petla
	
	MOV AH,01h	
	MOV CH,07h	
	MOV CL,07h	
	INT 10H 
	
	mov ah, 4ch
	int 21h
kod ends
end start
end

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