Technika cyfrowa i mikrokomputery

Transkrypt

Technika cyfrowa i mikrokomputery
Radosław Maciaszczyk
Mirosław Łazoryszczak
Sprzęt i architektura komputerów
Laboratorium
Temat:
Mikroprocesory i elementy asemblera
Katedra Architektury Komputerów i Telekomunikacji
1. M I KROPROCES ORY I EL E M EN TY A SEM BL ERA
1.1.
ARCHITEKTURA MIKROPROCESORA 8086
Schemat blokowy mikroprocesora 8086 przedstawia rys. 1.
Moduł współpracy z magistralą
Jednostka wykonawcza
magistrala wewnętrzna
1 2 3 4 5 6
magistrala
systemowa
kolejka instrukcji
FR
CS
bufory
sterowanie
IP
ALU
AH
AL
BH
BL
CH
CL
DH
DL
DS
SP
ES
BP
SS
sterowanie
SI
DI
Rys. 1 Schemat blokowy mikroprocesora 8086
Procesor 8086 jest procesorem 16-bitowym. Posiada bowiem 16-bitowe
rejestry oraz 16-bitową magistralę danych. Magistrala adresowa jest 20bitowa, co pozwala na uzyskanie 1MB przestrzeni adresowej.
Budowa rejestru znaczników (FR – flag register)
– SF – znacznik znaku
– ZF – znacznik zera
– PF – znacznik parzystości
– AF – przeniesienie pomocnicze
– CF – przeniesienie
– OF – nadmiar
– IF – interrupt
– DF – znacznik kierunku
– TF – znacznik pułapki
Rejestry robocze:
– AX [AH, AL]– akumulator
– BX [BH, BL]– rejestr bazowy
– CX [CH, CL]– rejestr zliczający
– DX [DH, DL]– rejestr danych
–
–
–
–
SP – wskaźnik stosu
BP – wskaźnik bazy
DI – rejestr adresu przeznaczenia
SI – rejestr adresu operandu źródłowego
Rejestry segmentowe:
– CS – segment programu
– DS – segment danych
– SS – segment stosu
– ES – segment dodatkowy
Tryb adresowania – sposób wyznaczania adresu argumentu lub wyniku
– natychmiastowe (MOV AX, 20 – w rejestrze AX zostanie zapisana
liczba 20)
– rejestrowe (MOV AX, BX – w rejestrze AX zostanie zapisana
zawartość rejestru BX)
– bezpośrednie (MOV AX, [40] – w rejestrze AX zostanie zapisana
zawartość komórki pamięci o adresie 40)
– pośrednie (MOV AX, [CX] – w rejestrze AX zostanie zapisana
zawartość komórki pamięci o adresie, który znajduje się w
rejestrze CX)
– bazowe (MOV AX, [BP])
– indeksowe (MOV AX, [SI])
–
bazowo indeksowe (MOV AX, [SI+BP])
Możemy wyróżnić następujące instrukcje procesora:
– arytmetyczno – logiczne
– przesłań
– skoków, obsługi pętli
– wywołań i powrotów z podprogramów
– obsługi rejestrów segmentowych
– operacje na ciągach słów
– rozkazy we/wy
1.2.
PRZYKŁADY PROGRAMOWA NIA MIKROPROCESORA 8086
Przykład 1
Napisać program obliczający wartość następującego wyrażenia:
A*C + B*D, gdzie: A = 13
B = 43 C = -4 D = 19
Rozwiązanie
Najpierw
należy
zamienić
poszczególne
wartości
na
liczby
hexadecymalne. Liczby ujemne powinny być zapisane za pomocą kodu U2.
Program nie ma charakteru ogólnego, ponieważ wielkość i ilość rejestrów
została dopasowana do danych liczb.
A = 0Dh
B = 2Bh
C = FCh
D = 13h
Kod programu
1: MOV
2: MOV
3: IMUL
AL,0Dh
AH,0FCh
AH
4: MOV
BX,AX
5: MOV
6: MOV
7: MUL
AL,2Bh
AH,13h
AH
ADD
AX,BX
;Umieszczamy liczbę A w rejestrze AL
;Do rejestru AH wpisujemy liczbę C
;Mnożymy (ze znakiem) zawartość rejestru AL przez
;liczbę z rejestru AH, wynik umieszczony będzie
;w rejestrze AX
;Przechowujemy wynik pierwszego mnożenia
;w rejestrze BX
;Wpisujemy liczbę B do rejestru AL
;W rejestrze AH umieszczamy liczbę D
;Mnożymy (bez znaku) zawartość rejestru AL przez
;liczbę z rejestru AH, wynik umieszczony będzie
;w rejestrze AX
;Do wyniku pierwszego mnożenia dodajemy wynik
;drugiego mnożenia. Wynik dodawania (i całego
;wyrażenia) znajdzie się w rejestrze AX
Realizacja
Uruchomić program c:\emu8086. Wybrać w oknie startowym polecenie „new”,
wybrać „com template”. Przepisać podany kod (od miejsca „; add your code
here”. Sprawdzić czy składnia jest poprawna kompilując go. Po kompilacji
zapisać przykład na własnym dysku sieciowym. Następnie uruchomić program
i wykonać go w trybie krokowym obserwując poszczególne rejestry, oraz
rejestr znaczników (view->flags).
Podać wynik oraz jakie flagi zmieniły się w ostatnim kroku programu.
Dlaczego ?
Przykład 2
Napisać program obliczający sumę ośmiu kolejnych bajtów zapisanych
w pamięci począwszy od adresu DS:SI czyli 0700h:0000h
Rozwiązanie
W programie należy zastosować instrukcję pętli (LOOP). Ma ona
charakter skoku bezwarunkowego, przy czym z rozkazem tym związany jest
rejestr CX pełniący funkcję licznika pętli, dekrementowanego automatycznie
po każdym wykonaniu instrukcji LOOP.
Suma 8 bajtów wykracza poza zakres rejestru połówkowego, wobec tego
wynik musi być umieszczony w rejestrze 16-bitowym.
Kod programu
1:
2:
3:
4:
5:
6:
MOV
CX,08
XOR
AX,AX
XOR
SI,SI
XOR
BX,BX
loop1:
MOV
BL,[SI]
7: ADD
AX,BX
8: INC
SI
9: LOOP
loop1:
;Ustawiamy licznik pętli na 8
;Zerujemy rejestry AX, SI, BX (poniżej)
;Wczytujemy do rejestru BL pierwszy bajt z pamięci
;(rejestr SI wskazuje na pierwszy bajt tablicy).
;Ponieważ sumowane składniki są bajtami, musimy
;zatem pobierać pojedyncze bajty z pamięci. Stąd
;użycie rejestru BL. Gdyby użyto rejestru 16;bitowego jako miejsca przeznaczenia, wówczas
;procesor odczytałby całe słowo (dwa bajty) zamiast
;bajtu
;Wykonanie dodawania. Rejestr BH pozostaje
;wyzerowany, więc do akumulatora zawierającego
;cząstkowe wyniki dodawana jest zawartość rejestru
;BL
;Zwiększenie zawartości rejestru SI o 1, tak aby w
;kolejnym przebiegu pętli możliwy był odczyt
;kolejnego bajtu pamięci
;Wykonanie skoku do linii 5(stała loop1),
automatyczna ;dekrementacja rejestru CX i
sprawdzenie, czy jego ;zawartość jest większa od 0
Realizacja
Przpisać kod. Otworzyć okienko RAM (view-> memory), przejść do
adresu wskazywanego przez rejestr DS:SI. Krokowo wykonać program i
sprawdzić jak zmieniają się rejestry procesora. Wyliczyć ręcznie sumę i
porównać z uzyskanym wynikiem.
Przykład 3
Napisać program obliczający sumę dwóch wektorów 8 elementowych,
zadeklarowanych w kodzie programu, współrzedne tych wektorów zostaną
wyznaczone po asemblacji. Założyć, że wynik będzie 16 bitowy.
Rozwiązanie
Najpierw należy zadeklarować dwa wektory wejściowe oraz wektor
wynikowy. W pierwszym kroku następuje skok do właściwego kodu programu,
omijając deklaracje zmiennych. Korzystająć z rejestrów pośrednich należy
wczytać adresy wektorów. Do rejestru CX wczytujemy licznik pętli. Następnie
wykonujemy w pętli dodawanie dwóch wektrów zaś wynik zapisujemy do 3
wektora.
Kod programu
1: JMP start
2: vec1 db 1, 2, 5,
6, 9 ,11, 33, 99
3: vec2 db 11, 10,
7, 26, 99 ,1, 3,
9
4: vec3 db ?, ?, ?
, ? , ? , ? , ?
, ?
5: start:
6: LEA SI, vec1
7:
8:
9:
10:
11:
12:
LEA BX, vec2
LEA DI, vec3
MOV CX,8
XOR AX,AX
loop1:
MOV AL,[SI]
13: ADD AL,[BX]
14:
15:
16:
17:
18:
MOV [DI],AL
INC SI
INC BX
INC DI
LOOP loop1
;
;definiujemy wektory wejściowe (2 i 3) oraz wektor
;wyjściowy (4)
;etykieta start
;obliczenie efektywnego adresu wectora vec1 i
;umieszenie wartości w rejestrze SI
;adres początku wektora vec2 w rejestrze BX
;adres początku wektora vec3 w rejestrze DI
;ustawienie licznika pętli
;wyzerowanie rejestru AX
;wpisanie do rejestru AL wartośći spod adresu
;DS*16+SI
;dodanie do rejestru AL wartości spod adresu
;DS*16+BX
;przenieś wynik dodawania pod adres DS*16 + DI
;inkrementacja rejestru SI,BX,DI
;
;
;
Realizacja
Przepisz kod, przetestuj jego działanie.
Zadanie 1
Napisać program ustawiający wartość „1” w 6 bicie dowolnego adresu w
pamięci np 0700:0100.
Zadanie 2
Napisać program negujący 4 bit dowolnego adresu w pamięci np 0700:0100.
LITERATURA
[1]. Pr. zbiorowa, red. Stępień C.: Mikroprocesory firmy Intel, PWN, Warszawa 1992.
[2]. Turbo assembler. Quick Reference Guide. Borland International 1991.
[3]. Instrukcje procesorów rodziny 80x86 http://4programmers.net/Assembler/