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. MIKROPROCESORY I ELEMENTY ASEMBLERA 1.1. ARCHITEKT UR A M IKROPR O CESORA 8086 Schemat blokowy mikroprocesora 8086 przedstawia rys. 1. Moduł współpracy z magistralą Jednostka wykonawcza 1 2 3 4 5 6 magistrala wewnętrzna magistrala systemowa kolejka instrukcji FR AH BH AL BL CS IP ALU CH DH CL DL bufory DS SP ES BP sterowanie 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 20- bitowa, 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. PRZY KŁADY PRO G RAMOWA N IA MIK ROPROCESORA 8 0 86 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 1: MOV AL,0D ;Umieszczamy liczbę A w rejestrze AL 2: MOV AH,FC ;Do rejestru AH wpisujemy liczbę C 3: IMUL AH ;Mnożymy (ze znakiem) zawartość rejestru AL przez ;liczbę z rejestru AH, wynik umieszczony będzie ;w rejestrze AX 4: MOV BX,AX ;Przechowujemy wynik pierwszego mnożenia ;w rejestrze BX 5: MOV AL,2B ;Wpisujemy liczbę B do rejestru AL 6: MOV AH,13 ;W rejestrze AH umieszczamy liczbę D 7: MUL AH ;Mnożymy (bez znaku) zawartość rejestru AL przez ;liczbę z rejestru AH, wynik umieszczony będzie ;w rejestrze AX 8: ADD AX,BX ;Do wyniku pierwszego mnożenia dodajemy wynik ;drugiego mnożenia. Wynik dodawania (i całego ;wyrażenia) znajdzie się w rejestrze AX
Realizacja Uruchomić VirtualBOX oraz maszyne wirtualną DOS. Przejść do katalogu AFD (cd AFD). Uruchomić program AFD.EXE. Napisać w oknie poleceń: L NOP.BIN Napisać w oknie poleceń: A (przejście do trybu wpisywania komend) Przepisać podany kod (od adresu 103) Przeprowadzić symulację naciskając krokowe uruchomienie (klawisz F1). 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. 1: MOV CX,08 ;Ustawiamy licznik pętli na 8 2: XOR AX,AX ;Zerujemy rejestry AX, SI, BX (poniżej) 3: XOR SI,SI 4: XOR BX,BX 5: MOV BL,[SI] ;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 6: ADD AX,BX ;Wykonanie dodawania. Rejestr BH pozostaje ;wyzerowany, więc do akumulatora zawierającego ;cząstkowe wyniki dodawana jest zawartość rejestru ;BL 7: INC SI ;Zwiększenie zawartości rejestru SI o 1, tak aby w ;kolejnym przebiegu pętli możliwy był odczyt ;kolejnego bajtu pamięci 8: LOOP 5 ;Wykonanie skoku do linii 5(stała loop1), automatyczna ;dekrementacja rejestru CX i sprawdzenie, czy jego ;zawartość jest większa od 0 Realizacja Przepisać kod. 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. Poczynając od adresu DS:00 wpisać 01 04 06 07 12 23 48 00 00 00 Poczynając od adresu DS:10 wpisać 11 23 12 ad 0f 4e 90 00 00 00 Poczynając od adresu DS:20 wpisać 00 00 00 00 00 00 00 00 00 00 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. 1: MOV SI,00 2: MOV BX,10 3: MOV DI 20 4: MOV CX,08 5: XOR AX,AX 6: MOV AL,[SI] 7: ADD AL,[BX] 8: MOV [DI],AL 9: INC SI 10: INC BX 11: INC DI 12: LOOP 6 LITERATURA Realizacja Przepisz kod, przetestuj jego działanie. Zapisz co jest wykonywane dla każdej instrukcji 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. [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/