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