Wprowadzenie do Architektury komputerów Asembler procesorów rodziny x86
Budowa procesora rodziny x86
Rejestry procesora 8086 ogólnego przeznaczenia Dla procesorów 32-bitowych: EAX, EBX, ECX, EDX Dla procesorów 64-bitowych: RAX, RBX, RCX, RDX
Rejestry wskaźnikowe i indeksowe Dla procesorów 32-bitowych: ESP, EBP, ESI, EDI Dla procesorów 64-bitowych: RSP, RBP, RSI, RDI
Adres fizyczny Rejestry segmentowe
Adres fizyczny i efektywny
Rejestr znaczników
Znaczniki
Szablon programu w asemblerze (TASM) TITLE Tytul Programu ; komentarz.model small.stack 100h.data zm_b DB 0 zm_w DW 1 zm_dd DD? komunikat db to jest komunikat,'$' znaki db abcdef, 20, 30 tablica db 1024 dup(0).code START: mov ax, @data mov ds, ax. <tutaj kod programu> mov ax, 4c00h int 21h END START Wypisanie stringu na ekranie MOV AH,09 LEA DX, <zmienna_str> INT 21h
Rozkazy mikroprocesora Rozkazy mikroprocesora 8086 można podzielić na siedem funkcjonalnych grup: 1. Rozkazy przesłania danych w pamięci. 2. Arytmetyczne. 3. Logiczne. 4. Operacje blokowe. 5. Skoki. 6. Operacje kontroli procesora. 7. Rozkazy wejścia/wyjścia.
Rozkazy przesyłania danych Rozkazy przesyłania danych pozwalają działać na danych bajtowych i 16-bitowych (słowa). Specjalnym ich przypadkiem są rozkazy przekazywania danych 32-bitowych, które służą do inicjalizacji rejestru (np. adresowego) i rejestru segmentu pełnym adresem 20-bitowym. Rozkazy przesyłania można podzielić na: uniwersalne, przesyłania adresów, przesyłania rejestru stanu.
MOV MOV - przeznaczony do przesyłania słów lub bajtów w operacjach typu rejestr-pamięć z (do) dowolnych rejestrów. Rozkaz ten może też przesyłać do pamięci dane określone w trybie prostym bez pośrednictwa rejestru. MOV reg, reg - pomiędzy rejestrami MOV mem,reg - z rejestru do pamięci MOV reg,mem - z pamięci do rejestru MOV reg,stała - stałej do rejstru MOV mem,stała - stałej do pamięci MOV reg,seg - z rejestru segmentowego do rejestru 16-bitowego MOV mem,seg - z rejestru segmentowego do pamięci MOV seg,mem - z pamięci do rejestru segmentowego
PUSH, POP PUSH - przesłanie słowa na szczyt stosu. PUSH reg/mem PUSH stała - prześlij 16-bitową wartość z rejestru lub pamięci na stos - prześlij stałą na stos POP - pobranie słowa ze szczytu stosu, a następnie modyfikacja wskaźnika stosu. POP reg,mem - pobierz daną ze stosu do rejestru lub do pamięci
LEA LEA - rozkaz przesyłania do rejestru 16-bitowego adresu efektywnego określonego w trybie odwołania do pamięci. Rejestrem wynikowym operacji może być rejestr uniwersalny, wskaźnik lub rejestr indeksowy. Rozkaz jest przeznaczony do pobierania adresu obiektu z pamięci w celu rutynowych działań na adresach. LEA reg,pamięć - zmienna pamięć jest komórką pamięci, której adres efektywny będzie wyliczony i przesłany do rejestru reg.
Tryby adresowania 1. Domyślny Przykłady: cbw ;domyślne operandy al i ax mul bx ;domyślny operand ax mul bl ;domyślny operand al 2. Natychmiastowy mov al, 5 mov al, A num EQU 5 imd= num-2 mov al, num mov [si],imd
Tryby adresowania 3. Rejestrowy mov ds, ax mov al, bl mov ebx, eax
Tryby adresowania 4. Bezpośredni Liczba DW 50... mov ax, Liczba mov ax, [Liczba] mov ax, [1234] mov ax, es:[12h] 5. Bezpośredni z przemieszczeniem Liczba DW 50 DW 40... mov ax, [Liczba+2] ;ładuje 40 do ax
Tryby adresowania 6. Bazowy mov ax, [bx] Tablica DB 5, 10, 15, 20... mov bx, OFFSET Tablica lea bx Tablica add bx, 3 mov al, [bx] ;ładuje 20 do al. lea bx, Tablica[3] mov al, [bx] ;ładuje 20 do al. Operator OFFSET: OFFSET wyrażenie
Tryby adresowania 7. Bazowy z przemieszczeniem TablicaDB 5, 10, 15, 20... mov al, [bx+3] ; ładuje 20 do al mov al, [bx]+3 ; ładuje 20 do al mov al, 3[bx] ; ładuje 20 do al. add bx, 3 mov al, [bx+tablica] ; ładuje 20 do al mov al, Tablica[bx] ; ładuje 20 do al
Tryby adresowania 8. Indeksowy mov ax, [si] TablicaDW 5, 10, 15, 20 mov si, OFFSET Tablica add si, 3 mov al, [si] 9. Indeksowy z przemieszczeniem mov mov ax, [si+4] ax, [di]+4 add si, 3 mov al, [si+tablica] mov al, Tablica[si]
Tryby adresowania 10. Bazowy indeksowany (z przemieszczeniem) mov ax, [bx+di] mov ax, [bx][si] mov ax, [di][bp] ;operand w segmencie stosu mov ax, [bx+si+3] mov ax, [bx][si+3] mov al, [bx+si+tablica] mov al, Tablica[bx][di] mov ax, [di+bp-2] ;operand w segmencie stosu
Rozkazy arytmetyczne Rozkazy arytmetyczne mikroprocesora 8086 mogą wykonywać cztery podstawowe działania arytmetyczne: dodawanie, odejmowanie, mnożenie i dzielenie, operując na danych 8- i 16-bitowych. Każde z działań może operować na liczbach przedstawionych na trzy sposoby: niekodowanych - zwykła reprezentacja dwójkowa liczb (np. 10000000b), na liczbach kodowanych dziesiętnie (np. 128), liczbach zapisywanych w postaci HEX (np. 80h).
ADD, SUB ADD - dodawanie arytmetyczne dwóch liczb. ADD reg,reg - dodawanie zawartości dwóch rejestrów ADD reg,mem - dodawanie do zawartości rejestru danej z pamięci ADD mem,reg - dodawanie do danej w pamięci zawartości rejestru ADD reg,stała - dodawanie danej natychmiastowej do rejestru ADD mem,stała - dodawanie danej natychmiastowej do danej w pamięci SUB - odejmowanie arytmetyczne dwóch liczb. SUB reg,reg - odejmowanie zawartości dwóch rejestrów SUB reg,mem - odejmowanie od zawartości rejestru danej z pamięci SUB mem,reg - odejmowanie od danej w pamięci zawartości rejestru SUB reg,stała - odejmowanie danej natychmiastowej od rejestru SUB mem,stała - odejmowanie danej natychmiastowej od danej w pamięci
INC, DEC INC - zwiększenie bajtu lub słowa o 1 (inkrementacja). INC reg - inkrementacja rejestru INC mem - inkrementacja komórki w pamięci DEC - zmniejszenie bajtu lub słowa o 1 (dekremantacja). DEC reg - dekrementacja rejestru DEC mem - dekrementacja komórki w pamięci
MUL, IMUL MUL - mnożenie liczb bez znaku. Operacja 8-bitowa pobiera pierwszy argument z AL, natomiast operacja 16-bitowa pobiera argument z AX. Wynik jest przekazywany w pierwszym przypadku do AX, natomiast w drugim przypadku do pary rejestrów AX i DX. MUL reg MUL mem - mnożenie przez rejestr - mnożenie przez zawartość komórki pamięci IMUL - jak wyżej dla liczb ze znakiem. IMUL reg - mnożenie przez rejestr IMUL mem - mnożenie przez zawartość komórki pamięci
DIV, IDIV DIV - dzielenie liczb bez znaku. Operacja dzielenia przez dzielnik 8-bitowy pobiera pierwszy argument z AX, natomiast operacja dzielenia przez dzielnik 16-bitowy pobiera argument z pary rejestrów AX i DX (DX jest starszym słowem wyniku). DIV reg DIV mem - dzielenie przez daną z rejestru - dzielenie przez daną z komórki pamięci IDIV - jak wyżej dla liczb ze znakiem.
Rozkazy logiczne, przesunięcia, obroty Rozkazy logiczne obejmują standardowy zbiór operacji: negacji, sumy, iloczynu i różnicy symetrycznej. Przesunięcia i obroty występują w ośmiu wariantach. Mogą być jedno- i wielokrokowe. Wyniki przekazują w rejestrze lub pamięci. Wariant krokowy odwołuje się do rejestru CL, jako źródła licznika przesunięcia. NOT - negacja każdego bitu liczby. NOT reg - negacja danej w rejestrze NOT mem - negacja danej w pamięci
AND, TEST AND - Iloczyn logiczny argumentów. AND reg,reg - iloczyn logiczny zawartości dwóch rejestrów AND reg,mem - iloczyn logiczny zawartości rejestru i danej w pamięci AND mem,reg - iloczyn logiczny danej w pamięci i zawartości rejestru AND reg,stala - iloczyn logiczny zawartości rejestru i stałej AND mem,stała - iloczyn logiczny danej w pamięci i zawartości rejestru TEST - testowanie wybranych bitów argumentów. Instrukcja ta wykonuje logiczną operację AND na swoich argumentach. Wynik nie jest nigdzie zapamiętywany, ale na jego podstawie ustawiane są znaczniki. TEST reg,reg - testowanie zawartości dwóch rejestrów TEST reg,mem - testowanie zawartości rejestru z daną w pamięci TEST mem,reg - testowanie danej w pamięci z zawartością rejsetru TEST reg,stała - testowanie zawartości rejestru z daną natychmiastową TEST mem,stała - testowanie danej w pamięci z daną natychmiastową
OR, XOR OR - suma logiczna argumentów. OR reg,reg - suma logiczna zawartości dwóch rejestrów OR reg,mem - suma logiczna zawartości rejestru i danej w pamięci OR mem,reg - suma logiczna danej w pamięci zawartością rejestru OR reg,stała - suma logiczna zawartości rejestru i danej natychmiastowej OR mem,stała - suma logiczna danej w pamięci z daną natychmiastową XOR - różnica symetryczna argumentów (suma modulo 2). Składnia jak dla instrukcji OR.
SHL, SHR SHL - przesunięcie logiczne w lewo. SHL mem,1 - przesunięcie logiczne komórki pamięci o 1 w lewo SHL reg,1 - przesunięcie logiczne zawartości rejestru o 1 w lewo SHL mem,cl - przesunięcie logiczne komórki pamięci o zawartość CL w lewo SHL reg,cl - przesunięcie logiczne komórki rejestru o zawartość CL w lewo SHR - przesunięcie logiczne w prawo. Składnia i argumenty jak dla SHL.
Skoki Rozkazy skoków można podzielić na: skoki zwykłe i warunkowe, wywołania podprogramów, powroty z procedur, rozkazy tworzenia iteracji, przerwania programowe.
Skoki warunkowe JE/JZ JL/JNGE JLE/JNG JB/JNAE JBE/JNA JNE/JNZ JNL/JGE JNLE/JG JNB/JAE JNBE/JA Skok, gdy równy/zero Skok, gdy mniejszy/nie równy lub nie większy Skok, gdy mniejszy lub równy/nie większy Skok, gdy poniżej/nie powyżej lub nie równo Skok, gdy poniżej lub równo/nie powyżej Skok, gdy nie równy/nie zero Skok, gdy nie mniejszy/większy lub równy Skok, gdy nie mniejszy lub równy/większy Skok, gdy nie poniżej/powyżej lub równo Skok, gdy nie poniżej lub równo/powyżej Po rozkazie skoku należy podać miejsce w programie gdzie należy skoczyć (najczęściej jest to ETYKIETA) Powyższe rozkazy najczęściej występują po instrukcji porównania CMP CMP A, B (A rejestr/adres, B rejestr/adres/stała) A i B to dwie dowolne wartości, które porównujemy. Wykonanie instrukcji CMP powoduje ustawienie odpowiednich flag procesora (OF, SF, ZF), a to właśnie na tej podstawie są wykonywane instrukcje skoku
Inne skoki CALL JMP RET IRET Skok do podprogramu (wywołanie procedury) Skok bezwarunkowy Powrót z podprogramu (procedury) Powrót z procedury obsługi przerwania Procedury <nazwa_procedury> PROC ;wszystkie rejestry wykorzystywane w procedurze - na stos (push) ; TUTAJ KOD PROCEDURY ;wszystkie rejestry wykorzystywane w procedurze - zdjąć ze stosu (pop) RET <nazwa_procedury> ENDP WYWOŁANIE PROCEDURY: CALL <nazwa_procedury>
Rozkazy kontroli iteracji LOOP - zmniejsza CX o 1 i wykonuje skok, gdy CX!= 0. LOOP nazwa_etykiety - skok do etykiety, gdy CX!= 0 UWAGA: Rozkazy kontroli iteracji wykorzystują rejestr CX jako licznik iteracji. Należy zatem pamiętać, aby w pętlach (bo do tego głównie będą wykorzystywane tego rodzaju skoki) uważać z modyfikacją rejestru CX. Poza tym zasięg tych skoków to -128 do +127 bajtów. Etykieta, do której wykonywany jest skok powinna się znajdować na ogół powyżej instrukcji kontroli iteracji.
Rozkazy przerwań programowych INT - przerwanie programowe. INT numer_przerwania ;wywołanie przerwania o podanym numerze RET - powrót z podprogramu. RET IRET - powrót z podprogramu obsługi przerwania. IRET
Rozkazy wejścia/wyjścia OUT - wysłanie danej do portu, numer portu można podać bezpośrednio, (liczba 8 bitowa), lub skorzystać z rejestru dx, dane w akumulatorze (AX,AL) Przykład: out dx,al out 70h,al - wysłanie bajtu z al to portu dx - wysłanie zawartości al do portu 70h IN - odebranie danej z portu, numer portu można podać bezpośrednio, (liczba 8 bitowa), lub skorzystać z rejestru dx, dane trafiają do akumulatora Przykład: in al,71h in al,dx - odczytanie bajtu z portu 71h i umieszczenie go w al - odczytanie bajtu z portu dx i umieszczenie go w al
Konwencje adresowania danych wielobajtowych Istnieją dwa sposoby zapisu danej wielobajtowej w pamięci, zwane konwencjami adresowania danych. Nazwy konwencji pochodzą z powieści Podróże Guliwera, w której odnosiły się one do dwóch społeczności, różniących się zasadami jedzenia gotowanych jaj.
Little-Endian i Big-Endian
Dyrektywa ptr Dyrektywa ptr mówi procesorowi o tym jak ma traktować wskazaną komórkę pamięci byte ptr jako bajt 8 bit word ptr jako słowo 16 bit dword ptr jako podwójne słowo 32 bit Przykłady: Pamiętać o little endian! Młodszy bajt liczby jest umieszczony pod adresem o mniejszej wartości add al, byte ptr [ds:bx] mov byte ptr [si], 3 mov ax, word ptr [es:bx]