;=============================================================================;
; ;
; Plik : arch2.asm ;
; Format : COM ;
; Cwiczenie : Kod U2 ;
; Autorzy : Konrad Materka, Beata Mazurkiewicz, 6, środa, 14:15 ;
; Data zaliczenia: 28.03.07 ;
; Uwagi : Program wczytuje z klawiatury dwie liczby calkowite ;
; z przedzialu [-32768..32767] wprowadzane w postaci znakow ;
; ASCII, konwertuje je do 16-bitowej postaci obliczeniowej ;
; w kodzie U2, oblicza ich sume reprezentowana w 32-bitowej ;
; postaci kodu U2, a nastepnie dokonuje jej konwersji do ;
; postaci znakow ASCII i wyswietla ja w tej postaci na ;
; ekranie. ;
; ;
;=============================================================================;
.MODEL TINY
MAX_ZNAKOW EQU 6 ; maksymalna liczba znakow
; liczby wprowadzanej przez
; uzytkownika
CRLF EQU 13,10 ; znak nowej linii
Kod SEGMENT
ORG 100h
ASSUME CS:Kod, DS:Kod, SS:Kod
Start:
jmp Poczatek ;przeskocz do obszaru danych
Test1 DB 255
Test2 DB 255
Skladnik1 DW 0
Skladnik2 DW 0
Suma DD 0
Bufor1 DB MAX_ZNAKOW DUP (?)
Bufor2 DB MAX_ZNAKOW DUP (?)
BuforWynik DB MAX_ZNAKOW + 2 DUP (?)
txtPowitanie DB "Program sumuje dwie liczby calkowite z zakresu "
DB "[-32768..32767].$"
txtZlec1 DB CRLF,"Podaj pierwsza liczbe: $"
txtZlec2 DB CRLF,"Podaj druga liczbe: $"
txtWynik DB CRLF,"Wynik wynosi: $"
pozaZakresem DB CRLF,"Przekroczenie zakresu.$"
CzyUjemna DB 0 ; czy rozpatrujemy liczbe dodatnia czy ujemna
Dziesiec DW 10 ; podstawa systemu liczbowego
Mnozenia DB 0
maxWartosc DB "-65536$"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WczytajZnak MACRO
; Dzialanie:
; Makro wczytuje znak z klawiatury bez echa.
; Uzywane rejestry:
; AH
mov ah, 08h
int 21h
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WyswietlZnak MACRO Znak
; Dzialanie:
; Makro wyswietla podany znak na ekranie.
; Parametry:
; Znak - znak do wyswietlenia
; Uzywane rejestry:
; AH, DL
mov dl, Znak
mov ah, 02h
int 21h
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WyswietlNapis MACRO Napis
; Dzialanie:
; Makro wyswietla podany napis zakonczony znakiem '$' na ekranie.
; Parametry:
; Napis - napis do wyswietlenia
; Uzywane rejestry:
; AH, DX
mov dx, OFFSET Napis
mov ah, 09h
int 21h
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WczytISkonwU2 MACRO Bufor, LiczbaZnakow
; Dzialanie:
; Makro wczytuje z klawiatury znaki traktujac je jako liczbe
; w postaci ciagu znakow ASCII i konwertuje ja do postaci obliczeniowej
; w kodzie U2.
; Parametry:
; Bufor - bufor, gdzie umieszczane beda wczytywane znaki
; LiczbaZnakow - maksymalna liczba znakow do wczytania
; Wyjscie:
; CF - 0 gdy powodzenie, 1 gdy niepowodzenie
; AX - o ile CF=0 - skonwertowana liczba w kodzie U2
; Uzywane rejestry:
; BX, CX
mov bx, OFFSET Bufor
mov cx, LiczbaZnakow
call WczytajLiczbe
mov bx, OFFSET Bufor
;mov cx, LiczbaZnakow
call KonwertujLiczbe
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WczytajLiczbe PROC NEAR
; Dzialanie:
; Procedura wczytuje ciag znakow z klawiatury stanowiacych liczbe
; w postaci ASCII i zapisuje je do bufora. Przeprowadzana jest kontrola
; dopuszczalnosci wprowadzanych znakow.
; Wejscie:
; DS:BX - bufor
; CX - maksymalna liczba znakow do wczytania
; Wyjscie:
; CX - ilosc wczytanych znakow
push ax
push dx
xor dx, dx ; wyzeruj licznik wczytanych znakow
xor ax, ax
PierwszyZnak:
WczytajZnak
cmp al,'-'
jz ZapiszZnak
cmp al,'0'
je SHORT WynikZero
cmp al,'1'
jb PierwszyZnak
cmp al,'9'
ja PierwszyZnak
dec cx ; jezeli bez minusa, to wczytujemy o 1 znak mniej
jmp SHORT ZapiszZnak
WynikZero: ; wprowadzono zero jako pierwszy znak, konczymy
mov cx,1
jmp SHORT ZapiszZnak
ZapiszZnak:
WyswietlZnak al
mov [bx],al
inc bx
inc dh
dec cx
jz Koniec
jmp SHORT WczytujDalej
WprowadzonoZero: ; sprawdza czy czasem nie wprowadzono -0, inne przypadki dozwolone
cmp BYTE PTR [bx-1],'-'
jne ZapiszZnak
WczytujDalej:
WczytajZnak
cmp al,13
je NacisnietoEnter
cmp al,'0'
je SHORT WprowadzonoZero
cmp al,'1'
jb WczytujDalej
cmp al,'9'
ja WczytujDalej
jmp SHORT ZapiszZnak
NacisnietoEnter:
cmp BYTE PTR [bx-1],'-'
je WczytujDalej
Koniec:
xor cx,cx
mov cl,dh
pop dx ; odtworz rejestry wykorzystywane w procedurze
pop ax
ret
WczytajLiczbe ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KonwertujLiczbe PROC NEAR
; Dzialanie:
; Procedura konwertuje liczbe zapisana w buforze w postaci ciagu znakow
; ASCII do 16-bitowej postaci obliczeniowej w kodzie U2.
; Wejscie:
; DS:BX - bufor
; CX - ilosc znakow w buforze
; Wyjscie:
; CF - 0 gdy powodzenie, 1 gdy niepowodzenie
; AX - o ile CF=0 - skonwertowana liczba w kodzie U2
; Uzywane rejestry:
; AX, BX, CX
push dx
xor dx,dx ; pomocniczy rejestr, tymczasowo kopiujemy tam znak
xor ax, ax ; w ax bedzie wynik
mov CzyUjemna,0
cmp BYTE PTR [bx],'-'
jne Konwertuj
Ujemna:
inc bx ; przeskakujemy minusa
dec cl ; czyli ilosc znakow nam sie zmniejsza
mov CzyUjemna,1 ; zapamietujemy na pozniej
Konwertuj:
mul Dziesiec ; pomnoz ax przez 10
jo ZakresPrzekroczny ; jesli wystapil nadmiar ustaw znacznik CF i zakoncz program
mov dl,[bx]
sub dx,'0' ; zapamietaj znak w buforze
add ax, dx ; dodaj skonwertowany znak do ax
inc bx ; zwieksz pozycje wskaznika w buforze
dec cl
jnz Konwertuj
; sprawdzamy zakresy i robimy ostanie konwersje
cmp CzyUjemna, 1
je SprawdzUjemna ; sprawdzamy granice dolna
cmp ax, 32767
ja ZakresPrzekroczny
jmp SHORT Wynik
SprawdzUjemna:
cmp ax, 32768
ja ZakresPrzekroczny ; sprawdzamy dolna granice
neg ax ; jezeli OK, to zamieniamy wartosc modulu na ujemna w U2
Wynik:
clc ; zeruj flage CF
jmp SHORT KoniecP
ZakresPrzekroczny:
stc ; ustaw flage CF
mov dx,OFFSET pozaZakresem
mov ah, 09h
int 21h
KoniecP:
pop dx
ret
KonwertujLiczbe ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KonwertujLiczbe2 PROC NEAR ;; inna wersja algorytmu
; Dzialanie:
; Procedura konwertuje liczbe zapisana w buforze w postaci ciagu znakow
; ASCII do 16-bitowej postaci obliczeniowej w kodzie U2.
; Wejscie:
; DS:BX - bufor
; CX - ilosc znakow w buforze
; Wyjscie:
; CF - 0 gdy powodzenie, 1 gdy niepowodzenie
; AX - o ile CF=0 - skonwertowana liczba w kodzie U2
; Uzywane rejestry:
; AX, BX, CX
push dx
xor dx,dx ; pomocniczy rejestr, tymczasowo kopiujemy tam ax
xor ch,ch ; licznik mnozen
xor ax, ax ; w ax bedzie wynik
mov CzyUjemna,0
cmp BYTE PTR [bx],'-'
jne Rozpocznij2
Ujemna2:
inc bx ; przeskakujemy minusa
dec cl ; czyli ilosc znakow nam sie zmniejsza
mov CzyUjemna,1 ; zapamietujemy na pozniej
Rozpocznij2:
mov Mnozenia, cl ; ile razy pomnozyc przez, najpierw wpisujemy ilosc cyfr
dec Mnozenia ; ale mnozymy n-1 razy, wiec zmniejszamy
Konwertuj2:
xor ax,ax
mov al, BYTE PTR [bx]
sub al, '0'
mov ch,Mnozenia
or ch,ch
jz PoMnozeniu2 ; jezeli mnoznik jest rowny zero, to nie wykonujemy mnozenia
; w przeciwnym wypadku mnozymy odpowiednio n-1 razy
Mnoz2:
push dx
mul Dziesiec
pop dx
jo ZakresPrzekroczny2 ; przy naszych liczbach i tak nigdy nie przekroczy zakresu
dec ch
cmp ch,0
ja Mnoz2
PoMnozeniu2:
add dx,ax
;jo ZakresPrzekroczny2
inc bx ; bierzemy kolejny znak
dec Mnozenia ; kolejna liczbe mnozymy mniej razy
dec cl ; zmniejszamy ilosc liczb ktore pozostaly
jnz Konwertuj2 ; i sprawdzamy czy czasem nie byla to ostania
; nie ma wiecej znakow, wiec...
; sprawdzamy zakresy i robimy ostanie konwersje
cmp CzyUjemna, 1
je SprawdzUjemna2 ; sprawdzamy granice dolna
cmp dx, 32767
ja ZakresPrzekroczny2
jmp SHORT Wynik2
SprawdzUjemna2:
cmp dx, 32768
ja ZakresPrzekroczny2 ; sprawdzamy dolna granice
neg dx ; jezeli OK, to zamieniamy wartosc modulu na ujemna w U2
Wynik2:
clc ;zeruj flage CF
mov ax,dx
jmp SHORT KoniecP2
ZakresPrzekroczny2:
stc ;ustaw znacznik CF
mov dx,OFFSET pozaZakresem
mov ah, 09h
int 21h
KoniecP2:
pop dx
ret
KonwertujLiczbe2 ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Sumuj MACRO Skladnik1, Skladnik2, Suma
LOCAL LiczbaUjemna, Ustaw, Ustaw2, KoniecSumuj
; Dzialanie:
; Makro dodaje dwie liczby 16-bitowe, i zapamietuje wynik w postaci
; 32-bitowej.
; Parametry:
; Skladnik1 - pierwszy skladnik w 16-bitowej postaci obliczeniowej
; Skladnik2 - drugi skladnik w 16-bitowej postaci obliczeniowej
; Suma - miejsce, gdzie ma zostac umieszczony wynik w 32-bitowej postaci
; obliczeniowej
; Uzywane rejestry:
; AX
mov ax, Skladnik1 ; pobierz pierwszy skladnik
add ax, Skladnik2 ; dodaj drugi skladnik
js LiczbaUjemna ; czy znak jest minusem ( SF=1 ) ?
jno Ustaw ; nie jest minusem - sprawdz, czy nie wystapil nadmiar (OF=0) ?
mov dx, 0FFFFh
jmp SHORT KoniecSumuj
LiczbaUjemna:
jo Ustaw ; tak, jest minusem - sprawdz, czy wystapil nadmiar (OF=1) ?
mov dx, 0FFFFh ; jest umjemna, nie wystapil nadmiar
jmp SHORT KoniecSumuj
Ustaw:
mov dx, 0 ; jest dodatnia i nie przekroczylo zakresu
jmp SHORT KoniecSumuj
KoniecSumuj:
mov WORD PTR Suma, ax ; zapamietaj mlodsze slowo wyniku w zmiennej
mov WORD PTR Suma +2, dx ; uzupelnij zerem starsze slowo w zmiennej
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SkonwASCII MACRO Liczba, Bufor
LOCAL Zaneguj,Skonwertuj, Wyjdz, Zapisz
; Dzialanie:
; Makro konwertuje liczbe z 32-bitowej postaci obliczeniowej do postaci
; ciagu znakow ASCII, ktore zapamietuje w buforze.
; Parametry:
; Liczba - konwertowana liczba w 32-bitowej postaci obliczeniowej
; Bufor - bufor, gdzie umieszczone beda znaki liczby po konwersji
; Uzywane rejestry:
; AX, BX, DI
xor bx, bx
xor cx, cx
mov CzyUjemna, 0 ; domyslnie dodatnia
mov ax, WORD PTR Liczba ; mlodsze slowo w ax
mov dx, WORD PTR Liczba +2 ; starsze a dx
mov di, OFFSET Bufor
mov bx, 10
cmp dx, 0 ; dodatnia?
jz Skonwertuj ; jezeli tak, zacznij konwertowac
mov CzyUjemna, 1 ; ujemna - zapamietajmy to
Zaneguj: ; zamieniamy z U2 na dodatnia
not dx
not ax
add ax, 1 ; modyfikuje flage CF
adc dx, 0 ; doajemy 0 i flage CF
Skonwertuj:
div Dziesiec ; podziel mlodsze slowo przez 10
; wynik w ax, rezta w dx
add dl, '0' ; potrzebna nam reszta, dodajemy 30h i mamy znak ASCII
push dx
xor dx,dx
inc cx ; zliczanie znakow
cmp ax, 0 ; jezeli 0, to podzielilismy wystarczajaco duzo razy
jnz Skonwertuj ; jezeli nie, to konwertujemy dalej
cmp CzyUjemna, 1
jnz Zapisz ; dodatnia - nie wyswietlamy minusa
mov bl,'-' ; ujemna, wyswietla znak '-'
WyswietlZnak bl ; i przechodzi do wyswietlania liczby
Zapisz:
pop dx ; zdejmujemy znak
mov [di], dl ; ktory zapisujemy to tablicy
inc di ; bedziemy zapisywac w nastepnym miejscu
loop Zapisz ; zapisujemy kolejny znak
mov BYTE PTR [di], '$' ; oznaczamy koniec lancucha
WyswietlNapis Bufor ; wyswietlamy wynik
Wyjdz:
WyswietlZnak 13 ; wstawiamy enter
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Poczatek:
WyswietlNapis txtPowitanie ;wyswietl napis powitalny
WyswietlNapis txtZlec1 ;wyswietl napis nakazujacy wprowadzenie 1-szej liczby
WczytISkonwU2 Bufor1, MAX_ZNAKOW ;wczytaj liczbe z z klawiatury i
jc Blad ;jezeli wystapil blad - skocz
mov Skladnik1, ax ;w przeciwnym razie zapamietaj skonwertowana liczbe w zmiennej
WyswietlNapis txtZlec2 ;wyswietl napis nakazujacy wprowadzenie 2-giej liczby
WczytISkonwU2 Bufor2, MAX_ZNAKOW ;wczytaj liczbe z z klawiatury i skonwertuj do postaci U2
jnc Zsumuj ;jezeli nie wystapil blad - skocz
Blad:
mov ax, 4C01h ;w przeciwnym razie zakoncz program z kodem powrotu
int 21h ;oznaczajacym wystapienie bledu
Zsumuj:
mov Skladnik2, ax ;zapamietaj skonwertowana liczbe w zmiennej
Sumuj Skladnik1, Skladnik2, Suma ;zsumuj obie wprowadzone liczby i zapamietaj wynik w zmiennej
WyswietlNapis txtWynik ;wyswietl napis informujacy o wyniku
SkonwASCII Suma, BuforWynik ;skonwertuj wynik do postaci ASCII i zapamietaj w buforze
mov ax, 4C00h ; zakoncz program z kodem powrotu
int 21h ; zakonczenia poprawnego
Kod ENDS
END Start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;