Programowanie w asemblerze Architektura procesora 17 stycznia 2017
Zwana też ISA (Instruction Set Architecture). Klasyfikacja stos; akumulator; jeśli dodatkowe rejestry specjalizowane (np. adresowy), to extended accumulator; rejestr-pamięć rejestr-rejestr + load/store Ponadto w klasyfikacji uwzględnia się liczbę argumentów instrukcji (0 3) oraz liczbę adresów pamięci w instrukcji (0 3).
Różne poziomy uprzywilejowania Najprostsza wersja: zwykły (user) systemowy (supervisor). Ale na procesorach Intela 4 poziomy (0 3), choć w praktyce tylko 2 sa używane.
Model pamięci Problem wyrównania (alignment) używania adresów będacych wielokrotnościa pewnej wartości. Przykład: Pentium II ma 36-bitowe adresy, ale tylko 33-bitowa szynę adresowa. Trzy dolne bity adresu na szynie maja zawsze wartość 0. W efekcie zawsze pobierane jest 8 bajtów.
Kolejność bajtów w większych jednostkach Dwie możliwości: little endian: najmniej znaczacy bajt jako pierwszy, wymusza czytanie napisów (string) bajt po bajcie, inaczej odwrotna kolejność w rejestrze wielobajtowym; big endian: standard dla sieci.
Rejestr stanu procesora Zawiera często bit(y) aktualnego trybu pracy, co umożliwia sprzętowa realizację trybu uprzywilejowanego. Flagi w nim zawarte dziela się na warunkowe, sygnalizujace wynik ostatniej operacji; sterujace, służace do ustalania trybu pracy.
Flagi w procesorze Pentium SF (znak) najwyższy bit wyniku ostatniej operacji arytmetyczno-logicznej (czyli 1 gdy wynik < 0); ZF (zero) ustawiana gdy wynik ostatniej operacji arytmetyczno-logicznej był zerem; PF (parzystość) ustawiana gdy dolny bajt wyniku ma parzysta liczbę jedynek; CF (przeniesienie) ustawiana gdy podczas wykonywania operacji arytmetyczno-logicznej powstało przeniesienie (czyli istotna dla liczb bez znaku), ale używana czasem także w innych sytuacjach; OF (przepełnienie) ustawiana gdy podczas wykonywania operacji arytmetyczno-logicznej powstało przepełnienie (czyli istotna dla liczb ze znakiem); IF (przerwania) zezwala na przyjmowanie przerwań; DF (kierunek) wyznacza kierunek przebiegu operacji dla przesłań blokowych, 0 oznacza zwiększanie adresu.
Instrukcje maszynowe Postać instrukcji maszynowych Ciag bajtów o zmiennej długości ( CISC ) Słowo: (prawie) wszystkie instrukcje maja tę sama długość ( RISC ) Struktura instrukcji Podzielone na pola, podział może być różny dla różnych grup instrukcji. Czasem poprzedzane dodatkowym prefiksem, wpływajacym na interpretację właściwej instrukcji albo zawierajacym dodatkowa część adresu. W niektórych opisach prefiks uważany jest za osobna instrukcję.
Instrukcje maszynowe Pola: kodu operacji, określa operację do wykonania trybu adresowania, określa sposób wyznaczania argumentu lub adresu efektywnego. Podaje regułę interpretacji dla pól adresowych, np. może określać, czy instrukcja operuje na bajtach, słowach itd. (jeśli informacja ta nie jest zawarta w kodzie instrukcji). adresowe, wskazuje komórkę w pamięci lub rejestr procesora Moga też występować pola specjalne, np. podajace liczbę przesunięć w przypadku przesunięć i obrotów.
Obliczanie adresu efektywnego Adres efektywny = ostateczny adres w odwołaniu do pamięci, otrzymany w wyniku przetwarzenia zleconego zadanym trybem adresowania. Przestrzeń adresowa. Rejestry segmentowe, tablica segmentów. Deskryptory segmentów.
Repertuar instrukcji Typy instrukcji: Arytmetyczno-logiczne. Dodawanie, odejmowanie, mnożenie i dzielenie całkowite. ADD, ADC, INC, SUB, SBB, DEC, MUL, DIV, CMP Osobne operacje arytmetyczne dla innych sposobów reprezentacji liczb (np. BCD, ASCII, zmiennopozycyjne). Arytmetyka z nasyceniem (saturating): gdy wynik za duży ustawia się największa dopuszczalna wartość. Stosowana w DSP (np. MMX w Pentium).
Repertuar instrukcji (c.d.) Operacje Boole owskie, argumenty traktowane jako ciagi bitów, operacja wykonywana na parze odpowiadajacych sobie bitów. NOT, AND, OR, XOR, TEST Obroty i przesunięcia. Obroty cykliczne ROR, ROL, RCR, RCL Przesunięcia logiczne i arytmetyczne (dzielenie/mnożenie przez 2) SHL, SHR, SAL, SAR
Repertuar instrukcji (c.d.) Przesłania danych. Służa do przepisywania lub zmiany zawartości rejestru/komórki pamięci w inne miejsce: MOV, XCHG. Operacje na stosie: PUSH, POP, PUSHF, POPF. Operacje wejścia/wyjścia: IN, OUT. Wiele procesorów dostarcza specjalne instrukcje złożone do zwartego zapisywania typowych ciagów operacji, np. przepisywania czy przeszukiwania całych bloków pamięci (LODS, STOS, MOVS, SCAS, CMPS, REP).
Repertuar instrukcji Sterujace. Instrukcje te zmieniaja normalna sekwencyjna kolejność wykonywania instrukcji, modyfikujac wartość licznika rozkazów. Argumentem (niekoniecznie jedynym) jest zwykle adres następnej instrukcji do wykonania: może być podany jako względny lub bezwzględny. Skoki bezwarunkowe (JMP) wykonywane zawsze. Rozgałęzienia (skoki warunkowe): skok jest wykonywany tylko jeśli spełniony był odpowiedni warunek. Warunek może polegać na sprawdzeniu odpowiedniej flagi lub flag, ustawianych zależnie od wyniku ostatniej instrukcji arytmetyczno logicznej tak jest na procesorach 80x86 Intela (instrukcje JZ/JE, JNZ/JNE, JC, JNC, JO, JNO, JP, JNP).
Repertuar instrukcji Sa osobne skoki dla liczb ze znakiem (JG, JGE, JL, JLE) i bez znaku (JA, JAE, JB, JBE). Inna możliwość to umieszczenie wyniku porównania w rejestrze i sprawdzanie go (np. procesor Alpha, ale także Pentium). Wada: zajmuje się cały rejestr. Ostatnia możliwość to instrukcje typu compare and branch, dokonujace zarówno porównania jak i skoku warunkowego (np. VAX, PA-RISC), stwarza to jednak kłopoty przy agresywnym przetwarzaniu potokowym.
Repertuar instrukcji Wywołanie/powrót z podprogramu. CALL, RET Przerwanie programowe i powrót z przerwania: INT, IRET. Pętle (LOOP, JCXZ, LOOPE, LOOPNE). Często instrukcja przeskoku warunkowego omijania pojedynczej następnej instrukcji.
Repertuar instrukcji Ręczne ustawianie flag. CLI, STI, CLC Instrukcja NOP wypełniacz. Specjalne. Moga być wykonywane tylko w trybie uprzywilejowanym. Obejmuja manipulowanie mechanizmami ochrony, zatrzymanie procesora (HLT).
Tryby adresowe Typy argumentów instrukcji. Tryby adresowe określaja sposób wyznaczania położenia argumentów.
Tryby adresowe niejawny (domyślny) mul ecx natychmiastowy, dana jest zawarta bezpośrednio w instrukcji mov eax,10 rejestrowy, argument znajduje się w rejestrze, którego numer (symbol) podaje pole adresowe add eax,ebx
Tryby adresowe bezpośredni, adres argumentu znajduje się w polu adresowym mov eax,[100] rejestrowy pośredni, adres argumentu znajduje się w podanym rejestrze mov eax,[esi] pośredni, w polu adresowym znajduje się adres komórki pamięci, w której znajduje się adres argumentu (nie występuje w serii 80x86). względny, w polu adresowym podane jest przesunięcie względem licznika rozkazów; najczęściej używany w skokach warunkowych jle 30
Tryby adresowe indeksowy, adres argumentu powstaje ze zsumowania dwóch składników podanych w instrukcji: adresu lub przesunięcia podanego w polu adresowym instrukcji i zawartości podanego rejestru, lub zawartości jednego lub dwóch rejestrów. Jeden z nich (zwykle ustalony) nazywamy baza, zaś drugi, często iteracyjnie zmieniany, indeksem. Rejestr może być skalowany: jego wartość podczas wyznaczania adresu efektywnego mnoży się np. przez 2. mov mov eax,[ebx+100] ecx,[ebx+esi] Dla 80x86 ogólny schemat adresu ma postać adres-bazowy + przesunięcie + indeks * rozmiar-elementu autoinkrementacja/autodekrementacja, polega na automatycznym zwiększeniu argumentu po wykonaniu (lub przed wykonaniem) instrukcji.
Tryby adresowe Dokumentacja firmowa podaje tryby dopuszczalne dla każdej instrukcji. Dla większości instrukcji dostępne sa wszystkie sensowne kombinacje trybów.
Specjalne tryby dla procesorów sygnałowych (DSP) cykliczny (modulo): podaje się adres bufora, automatyczne zwiększanie wskaźnika bufora z zawijaniem bit reverse (dla FFT): adres docelowy to odwrócenie n dolnych bitów adresu źródłowego.
Sposoby korzystania z rejestru uniwersalnego Jako akumulator. W rejestrze znajduja się dane do obliczeń określonych kodem instrukcji. Jako wskaźnik. Rejestr zawiera adres właściwego operandu instrukcji, a nie sam operand. Jako automatycznie zwiększany wskaźnik do przechodzenia po kolejnych komórkach pamięci. Przechodzenie w przód znane jest jako autoinkrementacja, przechodzenie w tył jako autodekrementacja. Najczęstsze zastosowanie to przetwarzanie danych tablicowych. Jako indeks (rejestr indeksowy). W tym przypadku zawartość rejestru dodawana jest do podanego w instrukcji adresu bazowego dajac adres operandu.
Operacje na bitach Instrukcja BT (Bit Test) wstawia wartość podanego bitu w argumencie do flagi CF. Instrukcja BTS (Bit Test and Set) wstawia wartość podanego bitu w argumencie do flagi CF i ustawia ten bit na 1. Klasyka systemów operacyjnych. Takie instrukcje zapewne należy poprzedzić prefiksem LOCK, zwłaszcza, gdy mamy kilka procesorów chętnych do majstrowania przy pamięci. Rodzina instrukcji SETcc ustawia podany rejestr bajtowy na 0 lub 1 zależnie od wyniku porównania (a ściślej od stanu flag). Przydatna dla operacji warunkowych, aby móc wykonać je nieco później.
Miscelannea Instrukcja LEA służy głównie do nadużyć (np. mnożenie przez 5), rzadko jest używana zgodnie z pierwotnym przeznaczeniem. Dodawanie dwóch rejestrów, wynik w trzecim: lea rax,[rdi + rsi] Instrukcja RDRAND zwraca (jeśli mamy szczęście) gwarantowana liczbę losowa. Instrukcja NOP nic nie robi (ale z wdziękiem). Kiedyś lubiana przez włamywaczy.
Zamiana Instrukcja XCHG zamienia zawartość swoich argumentów. Zastępuje trzy instrukcje MOV (lub XOR) i nie wymaga dodatkowej komórki roboczej. Może być używana do implementacji semaforów. Instrukcja BSWAP odwraca kolejność bajtów w argumencie. Przydatna do realizacji przesłań sieciowych.
Szybka zmiana poziomu ochrony Szybkie wołanie usług systemu operacyjnego = zmiana między poziomami ochrony 3 a 0 Para instrukcji SYSENTER, SYSEXIT Para instrukcji SYSCALL, SYSRET
Przykład: if if (x > 0) z += x; else z++; else: koniec: mov eax,[x] cmp eax,0 jle else add [z],eax jmp koniec inc [z]
Przykład: while while (n > 0) { z += z; n--; } mov eax,[z] while: cmp [n],0 jle koniec add eax,eax dec [n] jmp while koniec: mov [z],eax