I. Treści programowe
Instrukcje bezwarunkowego odwołania
programu, rozkazy wywołania podprogramów i powrotu do programu wywołującego,
etykiety.
II. Cel ćwiczenia
Nabycie
umiejętności programowania podprogramów oraz wykonywania do nich odwołań i powrotów.
III. Materiały dydaktyczne:
1.
Stos (PUSH/POP)
Stos - jest to
specjalny blok pamięci. Jak nazwa wskazuje wartości są odkładane tam jak na
stosie. Dla lepszego zobrazowania można wyobrazić to sobie jako pudełko z
książkami. Ostatnio włożona książka będzie wyjęta jako pierwsza (Last In - First Out / LIFO). Rozkaz PUSH odkłada
wartość na stos, natomiast POP zdejmuje
i zapisuje do rejestru czy zmiennej w pamięci.
mov ax, 5 ;AX
= 5
push ax ;AX na stos
pop bx ;BX = 5
mov ax, 7 ;AX
= 7
push ax ;AX na stos
push ax ;AX na stos
pop bx ;BX = 7
pop cx ;CX
= 7
2.
Skok bezwarunkowy
JMP –
instrukcja skoku bezwarunkowego, umożliwia przeskok do innego fragmentu
programu.
Przykład:
JMP nazwa_etykiety
3.
Procedury
CALL (wołaj) i RET (return - powrót) służą do
tworzenia procedur - części programu, które
będą używane częściej niż raz.
CALL
etykieta-
po wywołaniu zapamiętuje na stosie adres następnej instrukcji
programu a następnie przeskakuje do etykiety "etykieta" tak, jak to
robiła instrukcja JMP.
Po napotkaniu instrukcji RET procesor pobiera ze stosu
adres zapamiętany przez CALL i przeskakuje pod ten
adres czyli "wraca" do programu nadrzędnego.
Przykład:
procedura: ;
etykieta określająca nazwę procedury
;Kod podprocedury
;Kod podprocedury cd.
;Kod podprocedury cd.
RET ; Powrót do programu
nadrzędnego.
Przykład wywołania procedury:
CALL procedura
Przykładowa struktura programu pokazująca
wykorzystanie procedur zmieniających kolejność wywoływanych rozkazów.
.model tiny
.code
org 100h
start:
jmp początek
pokaz_znak:
mov al, 2
mov dl, 'A'
int 21h
ret
koniec:
mov ax, 4c00h
int 21h
poczatek:
call pokaz_znak
call pokaz_znak
jmp koniec
end start
4.
Funkcja i jej argumenty
Niektóre funkcje wymagają zewnętrznych
argumentów, które możemy przekazać na kilka sposobów, przez:
Najszybszym sposobem przekazywania argumentów
jest użycie rejestrów, jednak częściej używamy do tego celu stos. Funkcje
zakodowane w niemal wszystkich językach wyższego poziomu przekazują argumenty
przez stos.
Przykład programu, w którym zadeklarowano
dwie funkcje pobierające adres powrotu ze stosu do rejestru bx a następnie funkcja pobierz zapisuje pobrany znak na stosie. Funkcja pokaz
wewnątrz pobiera wartość ze stosy i wyświetla go na
ekranie. Wykorzystanie rejestru w tym przypadku nie do końca jest bezpieczne i należy
uważać aby wewnątrz funkcji nie zmienić jej wartości. Jest to adres powrotu.
.model tiny
.code
org
100h
tart:
jmp poczatek
pobierz:
pop bx
mov ah, 1
int 21h
push ax
push bx
ret
pokaz:
pop bx
mov ah, 2
pop
dx
int 21h
push bx
ret
poczatek:
call pobierz
call pobierz
call pokaz
call pokaz
push 'A'
call pokaz
mov ax, 4c00h
int 21h
end
start
Zanim wywołamy naszą funkcję odkładamy
wartości dla argumentów na stos przy użyciu instrukcji push,
zaś następnie zdejmujemy je z niego przy użyciu instrukcji pop.
5.
Opis przerwania 10h
Przerwanie 10h – przerwanie BIOS, obsługa
ekranu:
Funkcja 02h - ustawia kursor
tekstowy w podanym miejscu ekranu.
AH = 02h
BH = numer strony ekranu
DH = wiersz (row)
DL = kolumna (column)
Zakres:
Funkcja 09h - wyświetla znak na ekranie
wiele razy z określonym kolorem.
AH = 09h
AL = znak ASCII
BH = numer strony
BL = atrybut koloru
CX = ile razy wyświetlić
Atrybut koloru:
Np.:
·
07h
= biały na czarnym
·
0Ah
= zielony
·
1Eh
= żółty na niebieskim tle
·
4Fh =
biały na czerwonym tle
Funkcja 0fh - służy do odczytania
aktualnego trybu wideo oraz informacji o ekranie.
AH = 09h
Zwracana
wartość:
AL
= numer aktualnego trybu wideo
AH = liczba kolumn ekranu
BH = numer aktywnej strony ekranu
IV. Zadania:
Zadanie 1.
Napisz
program, w którym zadeklaruj trzy procedury:
-
„POBIERZ_ZNAKI” pobierającą dwa znaki z klawiatury oraz zapisującą kody tych
znaków do dwóch zmiennych o nazwie: ZNAK_1 i ZNAK_2.
-
„POKAZ_ZNAKI” wyświetlającą znaki na ekranie,
- „ZATRZYMAJ”
zatrzymującą program na czas trzech sekund
Wywołaj
procedury w następującej kolejności:
POBIERZ_ZNAKI
POKAZ
_ZNAKI
ZATRZYMAJ
POBIERZ_ZNAKI
POKAZ_ZNAKI
Zadanie 2.
Napisz
program, w którym zadeklaruj trzy procedury wyświetlające trzy różne napisy na
ekran. W każdej z nich wywołaj utworzoną wcześniej procedurę grupującą
powtarzające się fragmenty kodu.
Wszystkie
trzy procedury wywołaj w zadeklarowanej etykiecie „poczatek”,
do której użyj skoku bezwarunkowego.
Zadanie 3.
Poniższy
program ustawia kursor na współrzędne 0,0 oraz wyświetla tam znak ‘A’ w kolorze
czerwonym.
Zmodyfikuj
ten program tak, aby instrukcje dotyczące ustawiania kursora oraz wyświetlania
znaku na ekranie były zgrupowane w odpowiednie procedury. Kolejne wywołanie
procedury ustawiającej kursor powinno inkrementować wartość kolumny.
Poniższy
przykład ukazuje jak powinno wyglądać wywołanie procedury wyświetlającej znak
na ekranie „pokaz_znak”.
push 65 ;A
call pokaz_znak
push 66 ;B
call pokaz_znak
push 67 ;C
call pokaz_znak
Jako parametr
do procedury przekaż kolejne kody Ascii znaków
A B C. Do przekazania parametrów użyj stosu.
------------------------------------------------------
.model tiny
.code
org 100h
start:
mov
Row,
0
mov Col, 0
mov Colour, 5
mov ah,
2
mov dh,
Row
mov
dl, Col
int
10h
mov al,
Char
mov bl,
Colour
mov bh, 0
mov ah,
9
mov cx,
1
int 10h
mov ax,
4C00h
int 21h
Row db ?
Col db ?
Colour db ?
Char db ?
end start
------------------------------------------------------
Zadanie 4.
Napisz
program, w którym zadeklaruj procedurę wyświetlającą tekst na ekranie. Adres do
tekstu przekaż do procedury przez stos. Wywołaj procedurę kilak razy dla
różnych ciągów znaków.