All pastes #416873 Raw Edit

Miscellany

public text v1 · immutable
#416873 ·published 2007-03-30 15:24 UTC
rendered paste body
;=============================================================================;
;                                                                             ;
; 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;