Architektura komputerów II – laboratorium
Transkrypt
Architektura komputerów II – laboratorium
Architektura komputerów II – laboratorium dr inż. Grzegorz Bazydło [email protected], www.uz.zgora.pl/~gbazydlo Lista zadań nr 6 Zagadnienia Wykorzystanie stosu oraz makr i procedur w języku Assembler. Przykład Poniższy program wczytuje z klawiatury dwie liczby w zakresie od 0 do 65535 i wyświetla je na ekranie. Wczytywanie liczby zawarto w makrze wczytajLiczbe, a wyświetlanie liczby na ekranie w makrze wyswietlLiczbe. Program zawiera ponadto makro wyswietlTekst służące do wyświetlania tekstu na ekranie oraz procedurę nowaLinia do wyświetlania nowej linii. Przykład możesz także pobrać ze strony prowadzącego. .model tiny .386 .data ; zmienne potrzebne do realizacji makr wiersz db 8 dup (?) ; zmienna pomocnicza (potrzebna dla makra wczytajLiczbe) tablica dw 1, 10, 100, 1000, 10000 ; tablica pięciu liczb potrzebnych do ; zainicjowania zmiennej "pomoc" (potrzebna dla makra wczytajLiczbe) pomoc dw 10000 ; zmienna pomocnicza (potrzebna dla makr wczytajLiczbe i ; wyswietlLiczbe) wyswietlanieZer db 0 ; zmienna pomocnicza (potrzebna dla makra ; wyswietlLiczbe), znaczenie: 0 - nie, 1 - tak ; zmienne potrzebne do realizacji właściwego programu tekstPodajLiczbe db "Podaj liczbe: $" tekstKoniec db "Aby zakonczyc nacisnij dowolny klawisz...$" liczba1 dw 0 liczba2 dw 0 .stack 100h .code start: ; =================== makro wyswietlTekst ======================= ; wyświetla na ekranie tekst zapisany w zmiennej A wyswietlTekst MACRO A ; zapisanie danych na stosie push ax ; wrzuć na stos rejestr AX push dx ; wrzuć na stos rejestr DX mov dx, offset A mov ah, 09h int 21h ; przywrócenie danych ze stosu pop dx ; pobierz ze stosu rejestr DX pop ax ; pobierz ze stosu rejestr AX ENDM ; koniec makra ; =================== makro wyswietlTekst ======================= ; =================== makro wczytajLiczbe ======================= ; wczytywanie liczby od 0 do maks. 65535 i zapisanie jej w zmiennej A (typu DW) wczytajLiczbe MACRO A LOCAL petla ; zapisanie danych na stosie pushf ; wrzuć na stos rejestr flag push ax ; wrzuć na stos rejestr AX push bx ; wrzuć na stos rejestr BX 1 push cx push dx ; wrzuć na stos rejestr CX ; wrzuć na stos rejestr DX ; wczytywanie ciągu 6 znaków (5 cyfr i Enter) mov dx, offset wiersz mov (wiersz), 6 ; określenie ile maksymalnie może zostać wczytanych znaków – ; pozwalamy wpisać 5 cyfr i znak CR (Enter) mov ah, 0Ah int 21h ; wpisanie do zmiennej "pomoc" odpowiedniej wartości początkowej (w zależności od ; ilości wczytanych cyfr) xor ax, ax mov al, (wiersz+1) ; skopiuj do rejestru AL ilość wczytanych znaków (cyfr) sub ax, 1 ; odejmij od AX jeden (bo tablica indeksowana jest od 0) mov bl, 2 mul bl ; pomnóż rejestr AX razy 2 (bo tablica zawiera dwubajtowe ; elementy) mov si, ax mov ax, (tablica+si) ; skopiowanie wartości z tablicy odpowiadającej ilości ; wczytanych cyfr mov pomoc, ax xor dx, dx ; wyzerowanie rejestru DX mov A, 0 ; wyzerowanie zmiennej A mov si, 2 ; zmienna pomocnicza wykorzystywana do adresowania petla: xor mov sub mul add inc ax, ax al, (wiersz + si) ; można też zapisać: mov al, wiersz[si] al, 48 ; zamień kod cyfry w ASCII na cyfrę (np. '3' -> 3) pomoc ; AX*pomoc -> wynik: DX:AX; w AX wynik, w DX = 0 A, ax si ; zmniejszenie mnożnika (zmienna pomoc) 10 razy (np. z 10000 na 1000) xor dx, dx mov ax, pomoc mov bx, 10 div bx ; w AX wynik dzielenia (nowy dzielnik), DX = 0 mov pomoc, ax ; sprawdzenie warunku zakończenia pętli cmp pomoc, 0 ; sprawdź czy licznik pętli jest większy od 0 jne petla ; jeśli jest większy od zera to wykonaj pętlę jeszcze raz ; przywrócenie danych ze stosu pop dx ; pobierz ze stosu rejestr DX pop cx ; pobierz ze stosu rejestr CX pop bx ; pobierz ze stosu rejestr BX pop ax ; pobierz ze stosu rejestr AX popf ; pobierz ze stosu rejestr flag ENDM ; koniec makra ; =================== makro wczytajLiczbe ======================= ; =================== makro wyswietlLiczbe ======================= ; wyświetlenie 5-cio cyfrowej liczby na ekranie zawartej w zmiennej A wyswietlLiczbe MACRO A LOCAL petla LOCAL wyswietl LOCAL niewyswietlaj ; zapisanie danych na stosie pushf ; wrzuć na stos rejestr flag push ax ; wrzuć na stos rejestr AX push bx ; wrzuć na stos rejestr BX push cx ; wrzuć na stos rejestr CX push dx ; wrzuć na stos rejestr DX 2 mov mov xor mov pomoc, 10000 ; zmienna pomocnicza wyswietlanieZer, 0 ; zmienna pomocnicza dx, dx ; wyzerowanie rejestru DX cx, A petla: mov ax, cx div pomoc mov cx, dx ; DX:AX / pomoc -> wynik: AX, reszta: DX ; CX jako bufor (do przechowania reszty z dzielenia) mov cmp jne cmp dx, ax ; do rejestru DX skopiuj wynik dzielenia (cyfra w AX) dl, 0 ; czy to jest cyfra 0? wyswietl ; jeśli to nie jest cyfra 0 to ją wyświetl wyswietlanieZer, 1 ; jeśli to jest cyfra zero, to sprawdź czy wyświetlanie ; zer jest włączone jne nieWyswietlaj ; wyświetlanie zer nie jest włączone - nie wyświetlaj ; zera wyswietl: add dl, 48 ; dodaj 48 aby z cyfry zrobić kod cyfry w ASCII (np. 3 -> '3') mov ah, 02h ; wyświetl cyfrę int 21h mov wyswietlanieZer, 1 ; ustaw wyświetlanie zer jako włączone nieWyswietlaj: ; zmniejszenie dzielnika (zmienna pomoc) 10 razy (np. z 10000 na 1000) xor dx, dx mov ax, pomoc mov bx, 10 div bx ; w AX wynik dzielenia (nowy dzielnik), DX = 0 mov pomoc, ax ; sprawdzenie warunku zakończenia pętli cmp pomoc, 0 ; sprawdź czy licznik pętli jest większy od 0 jne petla ; jeśli jest większy od zera to wykonaj pętlę jeszcze raz ; przywrócenie danych ze stosu pop dx ; pobierz ze stosu rejestr pop cx ; pobierz ze stosu rejestr pop bx ; pobierz ze stosu rejestr pop ax ; pobierz ze stosu rejestr popf ; pobierz ze stosu rejestr ENDM ; koniec makra ; =================== makro wyswietlanieLiczby DX CX BX AX flag ======================= ; =================== właściwy program =============================== ; wpisanie do rejestru DS adresu segmentu danych mov ax, @data mov ds, ax wyswietlTekst tekstPodajLiczbe wczytajLiczbe liczba1 call nowaLinia wyswietlLiczbe liczba1 ; wywołanie makra z parametrem "liczba" call nowaLinia wyswietlTekst tekstPodajLiczbe wczytajLiczbe liczba2 call nowaLinia wyswietlLiczbe liczba2 ; wywołanie makra z parametrem "liczba" call nowaLinia wyswietlTekst tekstKoniec ; oczekiwanie na wciśnięcie klawisza przez użytkownika mov ah, 08h int 21h 3 ; zakończenie programu mov ah, 4Ch int 21h ; =================== właściwy program =============================== ; =================== procedura nowaLinia ======================= nowaLinia: push dx push ax mov dl, 0Ah mov ah, 02h int 21h pop ax pop dx ret ; =================== procedura nowaLinia ======================= end start Zadanie 1 Wykorzystując powyższy przykład napisz program, który wczyta dwie liczby całkowite (0 ≤ a ≤ b ≤ 255), a następnie wyświetli na ekranie ich sumę (a+b), różnicę (a–b), iloczyn (a*b) i wynik dzielenia całkowitego (a/b). Zadanie 2 Napisz program, który wczyta trzy długości boków trójkąta (liczby całkowite, 0 < a,b,c ≤ 9999) a następnie wyświetli na ekranie informację, czy istnieje trójkąt o takich bokach (warunek istnienia trójkąta – każdy bok trójkąta jest mniejszy od sumy dwóch pozostałych boków: a<b+c, b<a+c, c<b+a). Zadanie 3 (domowe) Napisz program, który wypisze na ekranie parzyste liczby naturalne w zakresie ([a,b]) podanym przez użytkownika (0 ≤ a<b ≤ 9999). Zadanie 4 (domowe) Napisz program, który wyświetli na ekranie sumę liczb naturalnych od 1 do podanej przez użytkownika liczby (2 ≤ a ≤ 360). Zadanie 5 (domowe) Napisz program, który wczyta jedną liczbę całkowitą (-65535 ≤ a ≤ 65535), a następnie wyświetli na ekranie wartość bezwzględną tej liczby. Zadanie 6 (domowe) Napisz program sumujący wprowadzane przez użytkownika liczby naturalne. Warunkiem zakończenia wprowadzania liczb jest podanie wartości 0. Wynik działania: Suma Suma Suma Suma Suma wynosi: wynosi: wynosi: wynosi: wynosi: 0. Podaj liczbe (0-koniec): 2 2. Podaj liczbe (0-koniec): 5 7. Podaj liczbe (0-koniec): 3 10. Podaj liczbe (0-koniec): 8 18. Podaj liczbe (0-koniec): 0 Zadanie 7 (bonus) Napisz program, który wczyta dowolną liczbę całkowitą (-10254 < a < 10255), a następnie sprawdzi i wyświetli informację, czy podana liczba jest mniejsza od zera, większa od zera czy równa zero. 4