Cześć, mam problem z wyświetlaniem informacji w swoim programie.
Wszystko się kompiluje, ale zamiast stringów, które zapisałem do zmiennych pokazują się symbole z ASCII. Nie wiem w czym tkwi problem, być może to zła deklaracja stacku.
Używam tasma, pracuję przy użyciu DosBoxa. Z góry dziękuję za każdą pomoc.
.MODEL SMALL
;###############################################################################
; Makra
;###############################################################################
Wczyt_znak MACRO ;makrodefinicja wczyt_znak - wczytująca znak
mov ah, 07h
int 21h
ENDM
Wys_znak MACRO Znak ;makrodefinicja wys_znak - wysyłająca znak na konsolę
mov dl, Znak
mov ah, 02h ;rozkaz do ah - /wyswietla znak znajdujacy sie w dl/
int 21h
ENDM
Wys_znaki MACRO Znaki ;makrodefinicja wys_znaki - wysyłająca znaki na konsolę
mov dx, OFFSET Znaki
mov ah, 09h ;rozkaz do ah - /wyswietli znaki od miejsca rozpoczecia zmiennej (dx) do '$'/
int 21h
ENDM
;###############################################################################
; Stack
;###############################################################################
Stosik SEGMENT STACK ;Segment Stosik - Początek
DB 100h DUP (?) ;rezerwacja 100h, czyli 256 bitów pamięci na stos
Stosik ENDS
;###############################################################################
; Dane
;###############################################################################
Dane SEGMENT
Tymczas0 db 7 dup (0) ;bufor tymczasowy, będzie potrzebny przy konwersji z U2 na ASCII
Tymczas1 db 7 dup (?) ;tablica na postac ASCII liczby
max_l_znakow EQU 7 ;deklaracja maksymalnej liczby znakow
Liczba1 dw 0 ;zmienna o wielkosci 16 bitow na liczbe
Nowa_linia EQU 13,10,'$' ;zmienna przechowujaca 'enter'
Nast_linia db 13,10,'$' ;zmienna przechowujaca 'enter'
Tekst_poczatek db "Input character! Proper range is [-32768..32767]. '-0' is wrong value!", nowa_linia
Tekst db "Out of range!", nowa_linia
Tekst1 db "Input value: $"
Tekst2 db "Program ends!"
Dane ENDS
;###############################################################################
; Program
;###############################################################################
Kod SEGMENT
ASSUME CS:Kod, DS:Dane, SS:Stosik
Start:
;funkcja Poczatek
Wys_znaki Tekst_poczatek
Wys_znaki Tekst1 ;wypisz na konsole Tekst1
mov di,OFFSET Tymczas1 ;przesuń początek bufora do rejestru indeksowego przeznaczenia (di) (jeszcze pustego w środku)
call Pobierz_liczbe ;wywolanie procedury pobierajaca liczbe
mov di,OFFSET Tymczas1 ;przesuń początek bufora do rejestru indeksowego przeznaczenia di (już zapełnionego przez liczby)
call Na_U2 ;wywolanie procedury zmieniajacej format liczby na U2
mov Liczba1, ax ;przesuniecie tego, co podal uzytkownik z ax do zmiennej Liczba
jmp Zakonczenie ;skocz do f. Zakoncz
Ponad_zakres:
;funkcja Ponad_zakres
Wys_znaki Tekst ;funkcja zajmujaca sie obsluga podania przez uzytkownika liczb spoza zakresu
jmp Zakonczenie ;skocz do f. Zakoncz
Zakonczenie:
Wys_znaki Tekst2
mov ax, 4C00h
int 21h ; do skonczenia programu
;###############################################################################
; Procedury
;###############################################################################
Na_U2: ;procedura Na_U2
mov ax,0 ;zerowanie ax
mov bx,10 ;ustawienie bx na 10
mov cx,0 ;zerowanie cx
mov dx,0 ;zerowanie dx
cmp BYTE PTR [di],'-' ;porownanie pierwszego znaku ze znakiem minusa '-'
je Liczba_znak ;jesli rowne, skocz do Liczba_znak
Liczba_kolejna: ;funkcja Liczba_kolejna
cmp BYTE PTR [di],'$' ;porownanie znaku ze znakiem konca
je Na_U2_ ;jesli rowne, skocz do Na_U2_
mov dl,[di] ;przesuniecie do dl tego, na co dl 'wskazuje'
sub dl,'0' ;odejmij od dl znak '0', czyli 48
push dx ;odlozenie dx na stos
mul bx ;mnożymy przez bx aby 'dobrac się' do dziesiątek, setek, tysięcy liczby
pop dx ;sciagamy dx ze stosu
add ax,dx ;dodajemy ax do dx i wynik wpisujemy do ax
cmp cl,1 ;sprawdzamy, czy liczba ujemna
cmp ax,32767 ;sprawdzamy, czy nie jest poza zakresem
ja Zakres_over ;jesli ponad zakresem, skocz do Zakres_over
inc di ;zwiekszenie di o 1, aby wskazywal 'o jedno dalej'
jmp Liczba_kolejna ;skocz do Liczba_kolejna
Zakres_over: ;funkcja zakres_over
clc ;ustawienie flagi CF na 0
jmp Ponad_zakres ;skocz do Ponad_zakres
Liczba_znak: ;funkcja Liczba_znak
cmp BYTE PTR [di+1],48d ;sprawdź, czy 0 (czyli czy -0)
je Zakres_over ;jeśli 0 (czyli -0), to skocz do Zakres_over
mov cl,1 ;przesuniecie do cl jedynki, aby odrozniac dodatnie od ujemnych
inc di ;zwiekszenie di o 1, aby wskazywal 'o jedno dalej'
jmp Liczba_kolejna ;skocz do Liczba_kolejna
Na_U2_: ;funkcja Na_U2_
cmp cl,1 ;sprawdzamy czy konwertować do U2 czy nie, porównując wartość rejestru cl, jeśli jest w nim 1 to konwertować
jnz Powrot ;jesli liczba nie jest ujemna zf ma wartość 0 i skaczemy do Powrot
neg ax ;negujemy bity w ax
Powrot: ;funkcja Powrot
stc ;ustawienie flagi CF na 1
ret ;wracamy tam, gdzie wywolana zostala procedura
;###############################################################################
Pobierz_liczbe: ;procedura Pobierz_liczbe
Powtorz: ;f. Powtorz
mov ax,0 ;zerowanie ax
mov bx,0 ;zerowanie bx
Wczyt_znak ;wczytywanie znaku
cmp al,0Dh ;porownanie tego, co w al z enterem
je Wczytywanie_stop ;jak rowne, to skocz do Wczytywanie_stop
cmp al,'-' ;porownanie tego, co w al z minusem
je Dodaj_znak ;jak rowne, skocz do Dodaj_znak
Dodaj_znak: ;funkcja Dodaj_znak
mov BYTE PTR [di],al ;zapis znaku z al do bufora
Wys_znak al ;wyswietlenie tego na ekranie
inc cx ;zwiekszamy cx o 1, jako licznik wprowadzonych cyfr
inc di ;zwiekszamy di o 1, aby wskazywal na kolejny bajt
cmp cx,max_l_znakow ;porownanie ile jest cyfr z maksymalna iloscia znakow
jne Powtorz ;jesli nie jest rowne, skocz do Powtorz
Wczytywanie_stop: ;funkcja Wczytywanie_stop
mov BYTE PTR [di],'$' ;przesuniecie znaku konca ('$') do miejsca wskazywanego przez di
Wys_znaki nast_linia ;wyswietlamy 'entera'
ret ;wracamy tam, gdzie wywolana zostala procedura
;###############################################################################
Kod ENDS ;koniec segmentu kodu
END Start