P
OLITECHNIKA
O
POLSKA
Instytut Automatyki i Informatyki
Laboratorium architektury komputerów
Operacje arytmetyczne oraz logiczne na
liczbach całkowitych w kodzie U2.
Kod binarny, ósemkowy i szesnastkowy
.
Ć
wiczenie Nr 1
Zaprojektowa
ć
i uruchomi
ć
program w asemblerze 80x86 realizuj
ą
cy wielokrotn
ą
operacj
ę
:
a. dzielenia
b. mno
ż
enia
c. logiczn
ą
=<
d. dodawania
e. logiczn
ą
>
f. odejmowania
g. logiczn
ą
<
h. modulo
dla liczb o słowie 8-bitowym w kodzie U2.
Dane wprowadzane s
ą
z klawiatury w kodzie binarnym. Kolejno
ść
wprowadzania
danych i wykonania operacji dowolna i wielokrotna. Na ekranie istnieje stał
ą
linia (linia polece
ń
), gdzie wprowadzamy polecenia oraz dane. Z klawiatury
przyjmujemy tylko nast
ę
puj
ą
ce klawisze :
- <L> - wybór dane1
- <P> - wybór dane2
- <W> - wykonanie operacji
- <1>, <0> - wprowadzenie warto
ś
ci danej
- <Enter> - akceptacja danej
- <BS> - korekta
- <Esc> - wyj
ś
cie z programu
Z chwil
ą
wprowadzenia danej z linii wy
ś
wietlamy j
ą
w stałym miejscu ekranu w
kodzie szesnastkowym, a w nawiasach [] w kodzie ósemkowym. Na ekranie
zmieniamy tylko te pola które uległy zmianie. W
ś
rodku mi
ę
dzy danymi na
ekranie umieszczamy znak operacji.
Na pocz
ą
tku programu dan
ą
1 oraz dan
ą
2 zerujemy i wy
ś
wietlamy je na ekranie a
polu wyniku spacje. Zmiana dowolnej danej „kasuje” na ekranie poprzedni wynik.
Dla operacji arytmetycznych wynik operacji wy
ś
wietlamy w stałym miejscu ekranu
w kodzie szesnastkowym, a w nawiasach [] w kodzie ósemkowym. Dla wyniku
operacji z bł
ę
dem (np. dzielenie przez 0) lub przekroczymy zakres liczby
wy
ś
wietlamy w polu wyniku „***”.
Przykładowy wygl
ą
d ekranu
Dana1 = 0A [012]
+
Dana2 = FF [177]
=
Wynik = 09 [011]
Linia polece
ń
: L 00001101
Materiały pomocnicze:
Pobieranie danych z klawiatury
1.
Wykrywanie naciśnięcia wybranych pojedynczych kodów ASCII
Siódma funkcja przerwania 21h umożliwia pobranie jednego znaku z klawiatury. Funkcja zwraca
wartość w rejestrze AL. W celu wykrycia naciśnięcia wybranych klawiszy należy napisać
procedurę odpowiednich porównań i skoków warunkowych (patrz skrócona lista rozkazów x86).
Instrukcja porównania ma następującą postać:
cmp arg1, arg2
np.:
cmp al,30h
W wyniku jej zadziałania ustawiane są odpowiednie flagi procesora. Kod ASCII z którym
porównujemy rejestr AL można podać w postaci cyfry (np.: 48, 30h) lub wstawienie zlecić
asemblerowi przez wstawienie w apostrofach znaku jaki nas interesuje (np. ‘0’).
Przykładowy fragment programu reagujący na naciśnięcie klawiszy + oraz - :
TASM
/
FASM
ety1:
mov ah,7
int 21h
cmp al,'+’
je ety1
cmp al,'-'
je ety2
jmp ety1
ety1:
; operacje
ety2:
;operacje
Wyświetlanie wartości zmiennych
1.
Wyświetlanie zmiennej w postaci binarnej
Najprostszy sposób wyświetlenia zmiennej w postaci binarnej polega na wysuwaniu
kolejnych bitów ze zmiennej przez flagę C w rejestrze flagowym procesora. Rozkaz
taki posiada mnemonik RCL. Przykładowa funkcja wyświetlająca wartość zmiennej
za pomocą wysuwania kolejnych bitów i wyświetlaniu 1, gdy flaga C jest ustawiona i
0, gdy nie jest ustawiona może wyglądać następująco:
TASM
/
FASM
wysw_bin:
mov cl,8
ety1:
push cx
rcl [zmienna],1
jc ety2
mov dl,'0'
jmp ety3
ety2:
mov dl,'1'
ety3:
mov ah,2
int 21h
pop cx
loop ety1
rcl [zmienna],1
ret
2.
Wyświetlanie zmiennej w kodzie ósemkowym
Wyświetlanie w kodzie ósemkowym polega na podziale zmiennej na 3 bitowe pola,
np.: wartość 01011110 należy podzielić na grupy 01 011 110 i wyświetlić kody
ASCII otrzymanych wartości tj. 136. W celu wyświetlenia pierwszej cyfry konieczne
jest przesunięcie 2 najstarszych bitów na pozycje 0 oraz 1 bajtu (z usunięciem
pozostałych bitów zmiennej) oraz dodaniem wartości 30h, w wyniku czego z cyfry 2
otrzymamy kod ASCII cyfry 2 (kod o numerze 50 dziesiętnie lub 32h szesnastkowo).
Przesunięcia bitowe mają mnemonik SHR dla przesunięcia w prawo oraz SHL w
lewo. Kolejne grupy bitów w identyczny sposób należy przesunąć na pozycje bitowe
0-2. Przykładowy program może wyglądać następująco:
TASM
/
FASM
wysw_oct:
mov al,[zmienna] ;pierwsza cyfra oct
shr al,6
add al,30h
mov dl,al
mov ah,2
int 21h
mov al,[zmienna] ;druga cyfra oct
shl al,2
shr al,5
add al,30h
mov dl,al
mov ah,2
int 21h
mov al,[zmienna] ; trzecia cyfra oct
and al,7
add al,30h
mov dl,al
mov ah,2
int 21h
ret
3.
Wyświetlanie zmiennej w postaci dziesiętnej
Wyświetlanie w kodzie dziesiętnym pojedynczego bajtu polega na wydzieleniu
wartości setek, dziesiątek i jedności (dla zmiennych o wielobajtowych będą
dochodziły kolejne potęgi dziesiątki – tysiące, dziesiątki tysięcy itd.).
Dzielenie instrukcją DIV wymaga podania jedynie dzielnika, gdyż dzielna musi
znajdować się w ustalonym rejestrze (rejestrach). Również wynik dzielenia znajduje
się również ustalonych rejestrach np.:
DIV BL
Powoduje wykonanie operacji dzielenia zmiennej znajdującej się w rejestrze AX
przez rejestr BL. Część całkowita z dzielenia znajdzie się w rejestrze AL, natomiast w
rejestrze AH znajdzie się reszta z dzielenia.
Kolejne operacje dzielenia umożliwiają uzyskanie kolejnych reszt z dzielenia, które
należy zamienić na kody ASCII cyfr. Dzielenia należy wykonywać dopóki część
całkowita z dzielenia jest większa niż 10. Przykładowy podprogram może wyglądać
następująco:
TASM
/
FASM
wysw_dec:
mov al,[zmienna]
mov ah,0
mov bl,10
div bl
mov dl,ah ;ah - jednostki,
add dl,30h ; al -setki i dziesiatki
push dx
mov ah,0
div bl ;ah - dziesiatki, al - setki
add ax,3030h
push ax
mov dl ,al
mov ah,2 ;wyswielt setki
int 21h
pop ax
mov dl,ah ;wyswietl dziesiatki
mov ah,2
int 21h
pop dx ;wyswietl jednostki
mov ah,2
int 21h
ret
4.
Wyświetlanie zmiennej w postaci heksadecymalnej
Wyświetlanie w kodzie heksadecymalnym jest bardzo podobne do wyświetlania w
kodzie ósemkowym. Polega na podziale zmiennej na 4 bitowe pola, np.: wartość
01011110 należy podzielić na grupy 0101 1110 i wyświetlić kody ASCII otrzymanych
wartości tj. 5E. W celu wyświetlenia pierwszej cyfry konieczne jest przesunięcie 4
starszych bitów na pozycje 4 młodszych bitów bajtu. Dla cyfr 0-9 wyświetlenie polega
na dodaniu wartości 30h, w wyniku czego otrzymamy kod ASCII cyfry. Dla wartości
większych niż 9 konieczne jest dodanie takiej wartości, aby w jej wyniku uzyskać
zakres liter A-F. Kod ASCII liter wynoszą:
A - 65, B – 66 … F – 70. Konieczne jest zatem dodanie wartości 55 w przypadku, gdy
w bajcie znajdują się liczby większe niż 9. Przykładowy podprogram może wyglądać
następująco:
TASM
/
FASM
wysw_hex:
mov al,[zmienna] ;pierwsza cyfra hex
shr al,4
cmp al,10
jb ety4
add al,55 ; kody ascii liter
jmp ety5
ety4:
add al,30h
ety5:
mov dl,al
mov ah,2
int 21h
mov al,[zmienna] ;druga cyfra hex
and al,0Fh
cmp al,10
jb ety6
add al,55 ; kody ascii liter
jmp ety7
ety6:
add al,30h
ety7:
mov dl,al
mov ah,2
int 21h
ret