Lista instrukcji mikroprocesora 8086 Programowanie w assemblerze
Lista instrukcji mikroprocesora 8086
Lista instrukcji mikroprocesora 8086
Lista instrukcji mikroprocesora 8086
Lista instrukcji mikroprocesora 8086 Procesor 8086 dysponuje bardzo obszernym zbiorem rozkazów. Można je zgrupować w 108 podstawowych typów, a większość z nich wykorzystuje różne tryby adresacji i ma rozmaite inne opcje. Gdy chodzi o oprogramowanie, procesor 8086 jest nadrzędnie kompatybilny z programami napisanymi dla procesorów typu 8080 i 8085 na poziomie asemblera, lecz nie na poziomie kodu wynikowego. Właściwość ta okazuje się przydatna przy unowocześnianiu systemów opartych na procesorach 8080 i 8085 drogą wymiany jednostki centralnej na typ 8086. Stosowane są następujące tryby adresacji: - rejestrowy bezpośredni (z określeniem źródła i przeznaczenia) - względny odniesiony do licznika rozkazów (przy rozkazach rozgałęzień) - bezwzględny (adres 16-bitowy)
Lista instrukcji mikroprocesora 8086 Operacje arytmetyczne Operacje arytmetyczne są wykonywane bezpośrednio na liczbach 8- i 16-bitowych, zarówno znakowych jak nie. Obejmują one dodawanie, odejmowanie, mnożenie i dzielenie. Przy dodawaniu i odejmowaniu dziesiętnym można stosować liczby dwucyfrowe zapisane w kodzie BCD. Gdy operuje się liczbami jednocyfrowymi BCD, dostępne są wszystkie działania arytmetyczne. Dodawanie i odejmowanie może być wykonywane także w rejestrach BX, CX i DX, gdy zachodzi potrzeba. Operacje logiczne Operacje logiczne obejmują funkcje AND, OR, EXCLUSIVE OR i NOT. Wykonywane są także wszystkie typowe operacje przesunięć arytmetycznych i cyklicznych, zerowania, inkrementacji, dekrementacji, negacji, uzupełnienia i porównania. Niektóre z nich mogą być zastosowane bezpośrednio do danych w pamięci.
Lista instrukcji mikroprocesora 8086 Transmisji danych Procesor może korzystać z rozmaitych rozkazów przesyłania danych w postaci bitów, bajtów, słów i cyfr w kodzie BCD. Istnieje możliwość transmisji bloków danych, przy czym rejestr CX jest stosowany do zliczania przesyłanych bajtów. Operacja tego typu jest przydatna w działaniach na łańcuchach znaków. Dane mogą być wysyłane na stos lub stamtąd pobierane. Stos ma własną przestrzeń adresową, odrębną od zwykłej pamięci danych. W razie potrzeby, w pamięci można utworzyć większą liczbę niezależnych stosów, przy czym jeśli dany stos nie jest używany, jego wskaźnik należy zachować w pamięci. Stosy są budowane w dół pamięci. Skoki Procesor 8086 dysponuje 26 rozkazami skoków warunkowych, spośród których 12 stanowi powtórzenia tych samych działań pod innymi nazwami, zaś 14 dotyczy rzeczywiście różnych typów skoków. Istnieją także rozkazy bezwarunkowego skoku i bezwarunkowego przejścia do podprogramu. Niektóre z nich pozwalają na skok do, lub wywołania procedury z innego segmentu pamięci programu.
język
Techniki programowania asemblerowego
Procedury
Procedury
Przekazywanie argumentów w rejestrach
Przekazywanie argumentów w rejestrach Przykład przedstawia trzy procedury, służące do wypisywania na konsoli danych 4-, 8- i 16-bitowych w postaci szesnastkowej. Procedura dla słowa 8-bitowego korzysta z procedury wypisywania tetrady, a procedura dla słowa 16-bitowego z procedury dla bajtu. Argument wywołania jest przekazywany w rejestrze AX lub jego mniej znaczącej części - AL.
Organizacja pętli
Organizacja pętli (przykład)
Organizacja pętli (opis) W pierwszej wersji procedury używamy licznika pętli w jako indeksu danej. Wadami takiego rozwiązania są: konieczność użycia dodatkowej zmiennej jako licznika pętli i użycie złożonego trybu adresowania; zaletą potrzeba inkrementacji tylko jednej zmiennej. W drugiej wersji pętla jest odliczana w dół. W porównaniu z wersją pierwszą mamy tu jeden rejestr użyty do zliczania iteracji i konieczność modyfikacji dwóch rejestrów w każdym obiegu pętli.
Organizacja pętli (trzecia wersja)
Organizacja pętli (wersja trzecia - opis) Wersja trzecia używa wskaźnika danych do określenia warunku wyjścia z pętli. W tym celu przed pętlą jest wyliczana wartość wskaźnika dla stanu po ostatniej iteracji. Wersja czwarta korzysta z instrukcji iteracyjnych x86. Instrukcja LODSB ładuje bajt spod adresu zawartego w rejestrze ESI do AL i inkrementuje ESI. Instrukcja LOOP dekrementuje ECX i wykonuje skok, jeśli nie osiągnięto wartości 0. Procedura jest krótka w zapisie, ale współczesne procesory x86 wykonują instrukcje iteracyjne na ogół wolniej, niż odpowiadające im sekwencje instrukcji prostych.
Korzystanie ze znaczników
Operacje wielokrotnej precyzji
Dodawanie i odejmowanie wielokrotnej precyzji
Dodawanie i odejmowanie wielokrotnej precyzji (opis) Dodawanie 64-bitowe jest realizowane poprzez dodawanie mniej znaczących słów 32-bitowych, a następnie dodawanie bardziej znaczących słów z uwzględnieniem przeniesienia wchodzącego (instrukcja ADC), wygenerowanego w pierwszym dodawaniu. W analogiczny sposób można zrealizować odejmowanie, zastępując instrukcję ADD instrukcją SUB,a instrukcję ADC - instrukcją SBB (odejmowania z uwzględnieniem pożyczki wchodzącej). Przy uogólnieniu dla liczb o dowolnej długości, sumowanie poszczególnych fragmentów danej jest realizowane w pętli przy użyciu instrukcji ADC, a przed pętlą znacznik przeniesienia jest zerowany. Należy zadbać, by żadna inna instrukcja w pętli nie modyfikowała znacznika przeniesienia W tym celu do inkrementacji adresów o 4 użyto instrukcji LEA.
Przesunięcia wielokrotnej precyzji
Przesunięcia wielokrotnej precyzji Przesunięcie o jeden bit danej wielokrotnej precyzji można uzyskać poprzez przesunięcie pierwszego elementu, w wyniku czego bit wysuwany trafi do znacznika przeniesienia, a następnie użycie instrukcji rotacji przez przeniesienie. Podczas kolejnych rotacji bit z poprzedniej fazy jest wsuwany do słowa poddawanego rotacji, a bit wysuwany ze słowa jest zapamiętywany w znaczniku przeniesienia. W postaci ogólnej, dla danej o dowolnej długości, do przesuwania używamy wyłącznie instrukcji rotacji przez przeniesienie, a przed rozpoczęciem przesuwania ustawiamy znacznik przeniesienia w stan zero. Można to zrobić przy użyciu dedykowanej instrukcji zerowania przeniesienia lub poprzez wykonanie dowolnej instrukcji logicznej (np. OR AL, AL). W procesorach rodziny x86 od modelu 386 w górę istnieją specjalne instrukcje przesunięć 64-bitowych z zapisem 32 bitów wyniku SHLD i SHRD. Można ich użyć do syntezy przesunięć wielokrotnej precyzji o dowolną liczbę bitów (<32).
Usuwanie skoków
Usuwanie skoków - przykład
Usuwanie skoków - opis Przykład ilustruje usunięcie skoku poprzez dość wyrafinowane zastosowanie instrukcji korekcji dziesiętnej. Sekwencja czterech pierwszych instrukcji procedury hex_digit zamienia wartość mniej znaczącej tetrady rejestru AL na jej reprezentację znakową w postaci cyfry szesnastkowej w kodzie ASCII.
Optymalizacja wywołania procedury
Optymalizacja wywołania procedury (przykład)
Optymalizacja wywołania procedury (opis) Kończąca procedurę hex_word sekwencja CALL hex_byte; RET została zastąpiona instrukcją skoku JMP hex_byte. Ponieważ etykieta hex_byte występuje bezpośrednio po tej instrukcji instrukcja skoku może zostać usunięta. Analogicznego zabiegu dokonano w procedurze hex_byte. Procedura hex_digit kończy się skokiem do procedury wyświetlania znaku. W ten sposób powstaje interesująca konstrukcja programu procedury wywołującej swoje własne zakończenie. Konstrukcja taka nie ma swojego odpowiednika we współczesnych językach wysokiego poziomu.
Błędy i złe nawyki
Drukarka - podstawowe operacje INT 17 - PRINTER - WRITE CHARACTER AH = 00h AL = pisany znak DX = numer drukarki (00h-02h) Wynik: AH = status drukarki Informacje: Rozkaz ten drukuje znak na drukarce Znaczenie poszczegolnych bitow statusu drukarki: Bit(y)znaczenie 7 busy[drukarka zajeta(jesli = 0)] 6 acknowledge[drukarka gotowa do przyjecia nastepnego znaku(jesli = 0)] 5 out of paper[brak papieru(jesli = 1)] 4 selected[drukarka jest wlaczona(jesli = 1)] 3 I/O error[drukarka sygnalizuje blad(jesli = 1)] 2-1 unused[nie uzywane] ******************************************* INT 17 - PRINTER - INITIALIZE PORT AH = 01h DX = numer drukarki (00h-02h) Wynik: AH = status drukarki Informacje: Rozkaz ten inicjuje port drukarki ************************************* INT 17 - PRINTER - GET STATUS AH = 02h DX = numer drukarki (00h-02h) Wynik: AH = status drukarki Informacje: Rozkaz ten podaje status drukarki *************************************
Programowanie myszy a) Sprawdzenie czy mysz jest zainstalowana: AX = 0000h Po wywolaniu przerwania 33h rejestr AX zawiera status myszy: AX = 0 - nie zainstalowana AX = 1 - zainstalowana Natomiast rejestr BX zawiera typ myszy: BX = 1 - z dwoma przyciskami BX = 0 - inna b) Wyswietlenie kursora myszy AX = 0001h Po wywolaniu przerwania 33h na ekranie pojawi sie kursor myszy. c) Skasowanie kursora myszy AX = 0002h Po wywolaniu przerwania 33h kursor myszy zniknie d) Odczyt pozycji kursora i stanu przyciskow AX = 0003h Po wywolaniu przerwania 33h: BX = stan przyciskow: (bit 0 = 1) - przycisniety lewy przycisk (bit 1 = 1) - przycisniety prawy przycisk (bit 2 = 1) - przycisniety srodkowy przycisk CX = kolumna w ktorej znajduje sie kursor DX = wiersz w ktorym ------//------
Programowanie klawiatury a) Odczyt znaku z klawiatury(bios) AH = 00h odczyt znaku z klawiatury podst. AH = 01h odczyt znaku z klawiatury rozszerzonej Po wywolaniu przerwania 16h AH = kod klawisza(tzw. scan code) AL = kod ASCII nacisnietego klawisza b) Sprawdzanie bufora klawiatury AH = 01h dla klawiatury podst. AH = 11h dla klawiatury rozszerzonej Po wywolaniu przerwania 16h jesli w buforze byl znak to: ZF = 0 AH = scan code znaku AL = jego kod ascii Jesli go nie bylo to: ZF = 1 c) Odczyt stanu klawiszy dotatkowych AH = 02h Po wywolaniu przerwania 16h rejestr AL: bit 0 - nacisniety prawy Shift bit 1 - nacisniety lewy Shift bit 2 - nacisniety Ctrl bit 3 - nacisniety Alt bit 4 - wlaczony Scroll lock bit 5 - wlaczony Num lock bit 6 - wlaczony Caps lock bit 7 - wlaczony insert