;=============================================================================; ; ; ; 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;