Szukaj…


Rejestry 16-bitowe

Kiedy Intel zdefiniował oryginalny model 8086, był to 16-bitowy procesor z 20-bitową szyną adresową (patrz poniżej). Zdefiniowali 8 rejestrów 16-bitowych ogólnego przeznaczenia - ale nadali im określone role dla niektórych instrukcji:

  • AX Rejestr akumulatorów.
    Wiele kodów operacyjnych albo przyjmowało ten rejestr, albo było szybszych, jeśli został określony.
  • DX Rejestr danych.
    Czasami było to łączone jako wysokie 16 bitów 32-bitowej wartości z AX - na przykład w wyniku zwielokrotnienia.
  • CX Rejestr rejestru.
    Zostało to wykorzystane w szeregu instrukcji zorientowanych na pętlę jako domyślny licznik dla tych pętli - na przykład LOOPNE (pętla, jeśli nie jest równa) i REP (powtarzany ruch / porównanie)
  • BX Rejestr podstawowy.
    Można to wykorzystać do indeksowania podstawy struktury w pamięci - żaden z powyższych rejestrów nie może być użyty do bezpośredniego indeksowania do pamięci.
  • SI Rejestr indeksu źródłowego.
    Był to domyślny indeks źródła do pamięci dla niektórych operacji przenoszenia i porównywania.
  • DI Rejestr indeksu celu podróży.
    Był to domyślny indeks miejsca docelowego w pamięci dla niektórych operacji przenoszenia i porównywania.
  • SP Rejestr wskaźnika stosu.
    Jest to najmniej rejestr ogólnego przeznaczenia w zestawie! Wskazywał na bieżącą pozycję na stosie, która została jawnie użyta do operacji PUSH i POP , domyślnie dla CALL i RET z podprogramami oraz BARDZO niejawnie podczas przerwań. Używanie go do wszystkiego innego było niebezpieczne dla twojego programu!
  • BP Rejestr wskaźnika bazowego.
    Kiedy podprogramy wywołują inne podprogramy, stos zawiera wiele „ramek stosu”. BP można wykorzystać do przechowywania bieżącej ramki stosu, a następnie, gdy zostanie wywołany nowy podprogram, można go zapisać na stosie, utworzyć nową ramkę stosu i użyć, a po powrocie z wewnętrznego podprogramu można przywrócić starą wartość ramki stosu .

Uwagi:

  1. Pierwsze trzy rejestry nie mogą być używane do indeksowania do pamięci.

  2. BX , SI i DI domyślnie indeksują do bieżącego segmentu danych (patrz poniżej).

     MOV    AX, [BX+5]     ; Point into Data Segment
     MOV    AX, ES:[DI+5]  ; Override into Extra Segment
    
  3. DI , gdy jest stosowany w operacjach typu pamięć-pamięć, takich jak MOVS i CMPS , używa wyłącznie dodatkowego segmentu (patrz poniżej). Tego nie można zastąpić.

  4. SP i BP domyślnie używają segmentu stosu (patrz poniżej).

Rejestry 32-bitowe

Kiedy Intel wyprodukował 80386, zaktualizował z 16-bitowego procesora do 32-bitowego. Przetwarzanie 32-bitowe oznacza dwie rzeczy: oba manipulowane dane były 32-bitowe, a adresy pamięci, do których uzyskiwano dostęp, były 32-bitowe. Aby to zrobić, ale nadal pozostają kompatybilne ze swoimi wcześniejszymi procesorami, wprowadzono zupełnie nowe tryby dla procesora. Był w trybie 16-bitowym lub 32-bitowym - ale można było zmienić ten tryb na zasadzie instrukcja po instrukcji dla danych, adresowania lub obu!

Przede wszystkim musieli zdefiniować rejestry 32-bitowe. Zrobili to, po prostu rozszerzając istniejące osiem z 16 bitów na 32 bity i nadając im „rozszerzone” nazwy z prefiksem E : EAX , EBX , ECX , EDX , ESI , EDI , EBP i ESP . Dolne 16 bitów tych rejestrów było takich samych jak poprzednio, ale górne połowy rejestrów były dostępne dla operacji 32-bitowych, takich jak ADD i CMP . Górne połówki nie były osobno dostępne, tak jak w przypadku rejestrów 8-bitowych.

Procesor musiał mieć osobne tryby 16-bitowe i 32-bitowe, ponieważ Intel używał tych samych kodów operacyjnych dla wielu operacji: CMP AX,DX w trybie 16-bitowym i CMP EAX,EDX w trybie 32-bitowym miały dokładnie te same kody ! Oznaczało to, że ten sam kod NIE może być uruchomiony w żadnym trybie:

Kod operacji „Przenieś natychmiast do AX ” to 0xB8 , po którym następują dwa bajty wartości bezpośredniej: 0xB8 0x12 0x34

Kod operacji „Przenieś natychmiast do EAX ” to 0xB8 , po którym następują cztery bajty wartości bezpośredniej: 0xB8 0x12 0x34 0x56 0x78

Tak więc asember musi wiedzieć, w jakim trybie jest procesor podczas wykonywania kodu, aby mógł wyemitować prawidłową liczbę bajtów.

Rejestry 8-bitowe

Pierwsze cztery rejestry 16-bitowe mogą mieć dostęp do swojej górnej i dolnej połowy bajtów bezpośrednio jako własne rejestry:

  • AH i AL są górnymi i dolnymi połówkami rejestru AX .
  • BH i BL są górną i dolną BX rejestru BX .
  • CH i CL to górne i dolne połowy rejestru CX .
  • DH i DL są górnymi i dolnymi połówkami rejestru DX .

Pamiętaj, że oznacza to, że zmiana AH lub AL natychmiast zmieni również AX ! Zauważ też, że jakakolwiek operacja na 8-bitowym rejestrze nie może wpłynąć na jego „partnera” - zwiększenie AL tak, że przepełnienie z 0xFF do 0x00 nie zmieni AH .

Rejestry 64-bitowe mają również wersje 8-bitowe reprezentujące ich niższe bajty:

  • SIL dla RSI
  • DIL dla RDI
  • BPL dla RBP
  • SPL dla RSP

To samo odnosi się do rejestrów R8 przez R15 : ich odpowiednie części niższy bajt są nazwane R8B - R15B .

Rejestry segmentów

Segmentacja

Kiedy Intel projektował oryginalny model 8086, istniało już kilka 8-bitowych procesorów, które miały 16-bitowe możliwości - ale chcieli stworzyć prawdziwy 16-bitowy procesor. Chcieli także stworzyć coś lepszego i bardziej wydajnego niż to, co już tam było, więc chcieli mieć dostęp do więcej niż 65 656 bajtów pamięci sugerowanych przez 16-bitowe rejestry adresujące.

Oryginalne rejestry segmentów

Dlatego wdrożyli ideę „Segmentów” - 64-kilobajtowego bloku pamięci indeksowanego przez 16-bitowe rejestry adresowe - który może być ponownie oparty na różnych obszarach całej pamięci. Aby przechowywać te bazy segmentów, uwzględniono rejestry segmentów:

  • CS Rejestr segmentu kodu.
    Zawiera on aktualnie wykonywany segment kodu, indeksowany przez niejawny rejestr IP (wskaźnik instrukcji).
  • DS Rejestr segmentu danych.
    Przechowuje domyślny segment danych przetwarzanych przez program.
  • ES Rejestr Extra Segment.
    Zawiera drugi segment danych, dla jednoczesnych operacji danych w całej pamięci.
  • SS Rejestr segmentu stosu.
    Przechowuje segment pamięci, który przechowuje aktualny stos.

Rozmiar segmentu?

Rejestry segmentowe mogą mieć dowolny rozmiar, ale ich szerokość 16 bitów ułatwia współpracę z innymi rejestrami. Następne pytanie brzmiało: czy segmenty powinny się pokrywać, a jeśli tak, to w jakim stopniu? Odpowiedź na to pytanie określałaby całkowity rozmiar pamięci, do którego można uzyskać dostęp.

Gdyby w ogóle nie zachodziło na siebie, przestrzeń adresowa wynosiłaby 32 bity - 4 gigabajty - wówczas zupełnie niespotykany rozmiar! Bardziej „naturalne” nakładanie się 8 bitów zapewni 24-bitową przestrzeń adresową lub 16 megabajtów. Ostatecznie Intel postanowił zapisać cztery dodatkowe piny adresowe na procesorze, czyniąc przestrzeń adresową 1 megabajtową z 12-bitowym nakładaniem się - uważali to za wystarczająco duże jak na razie!

Więcej rejestrów segmentów!

Kiedy Intel projektował 80386, zdali sobie sprawę, że istniejący pakiet 4 rejestrów segmentowych nie wystarcza do złożoności programów, które chcieli, aby mógł on obsługiwać. Dodali więc jeszcze dwa:

  • FS Rejestr dalekiego segmentu
  • GS Rejestr segmentu globalnego

Te nowe rejestry segmentów nie miały zastosowania wymuszonego przez procesor: były dostępne tylko dla wszystkiego, czego chciał programista.

Niektórzy twierdzą, że nazwy zostały wybrane, aby po prostu kontynuować motyw C , D , E istniejącego zestawu ...

Rejestry 64-bitowe

AMD jest producentem procesorów, który uzyskał licencję na projekt 80386 od Intela, aby produkować kompatybilne - ale konkurencyjne - wersje. Wprowadzili wewnętrzne zmiany w projekcie, aby poprawić przepustowość lub inne ulepszenia w projekcie, wciąż będąc w stanie wykonywać te same programy.

Dla pojedynczego Intela wymyślili 64-bitowe rozszerzenia do 32-bitowej konstrukcji Intela i stworzyli pierwszy 64-bitowy układ, który nadal może uruchamiać 32-bitowy kod x86. Intel skończył zgodnie z projektem AMD w swoich wersjach architektury 64-bitowej.

Wersja 64-bitowa wprowadziła szereg zmian w zestawie rejestrów, jednocześnie zachowując zgodność z poprzednimi wersjami:

  • Istniejące rejestry ogólnego przeznaczenia zostały rozszerzone do 64 bitów i nazwane prefiksem R : RAX , RBX , RCX , RDX , RSI , RDI , RBP i RSP .

    Ponownie, dolne połówki tych rejestrów były tymi samymi rejestrami z prefiksem E jak poprzednio, a górne połówki nie były dostępne niezależnie.

  • Dodano jeszcze 8 rejestrów 64-bitowych, które nie zostały nazwane, lecz jedynie ponumerowane: R8 , R9 , R10 , R11 , R12 , R13 , R14 i R15 .
    • 32-bitowa niska połowa tych rejestrów to R8D do R15D (D dla DWORD jak zwykle).
    • Dostęp do najniższych 16 bitów tych rejestrów można uzyskać, dodając W do nazwy rejestru: od R8W do R15W .
  • Można teraz uzyskać dostęp do najniższych 8 bitów ze wszystkich 16 rejestrów:
    • Tradycyjne AL , BL , CL i DL ;
    • Niskie bajty (tradycyjnie) rejestrów wskaźników: SIL , DIL , BPL i SPL ;
    • Oraz niski bajtach 8 nowych rejestrów: R8B przez R15B .
    • Jednak AH , BH , CH i DH są niedostępne w instrukcjach, które używają prefiksu REX (dla 64-bitowego rozmiaru argumentu lub dostępu do R8-R15 lub dostępu do SIL , DIL , BPL lub SPL ). W przypadku prefiksu REX wzorzec bitów kodu maszynowego, który kiedyś oznaczał AH oznacza zamiast tego SPL i tak dalej. Patrz Tabela 3-1 instrukcji obsługi instrukcji Intela (tom 2).

Zapis do rejestru 32-bitowego zawsze zeruje górne 32 bity rejestru o pełnej szerokości, w przeciwieństwie do zapisu do rejestru 8 lub 16-bitowego (który łączy się ze starą wartością, co stanowi dodatkową zależność przy wykonywaniu poza kolejnością ).

Rejestr flag

Gdy jednostka arytmetyczna logiczna x86 (ALU) wykonuje operacje takie jak NOT i ADD , oznacza wyniki tych operacji („stała się zero”, „przepełniona”, „stała się ujemna”) w specjalnym 16-bitowym rejestrze FLAGS . 32-bitowe procesory zaktualizowały to do 32 bitów i nazwały to EFLAGS , podczas gdy 64-bitowe procesory zaktualizowały to do 64 bitów i nazwały to RFLAGS .

Kody warunków

Ale bez względu na nazwę, rejestr nie jest bezpośrednio dostępny (z wyjątkiem kilku instrukcji - patrz poniżej). Zamiast tego poszczególne flagi są SETcc w niektórych instrukcjach, takich jak Skok warunkowy lub Zestaw warunkowy, znany jako Jcc i SETcc gdzie cc oznacza „kod warunku” i odwołuje się do poniższej tabeli:

Kod stanu Nazwa Definicja
E , Z Równa, zero ZF == 1
NE , NZ Nie równe, nie zero ZF == 0
O Przelewowy OF == 1
NO Bez przepełnienia OF == 0
S Podpisany SF == 1
NS Niepodpisany SF == 0
P Parytet PF == 1
NP Bez parzystości PF == 0
-------------- ---- ----------
C , B , NAE Noś, poniżej, nie powyżej lub równy CF == 1
NC , NB , AE No Carry, Not Below, Above or Equal CF == 0
A , NBE Powyżej, nie poniżej lub równa CF == 0 i ZF == 0
NA , BE Not Above, Below lub Equal CF == 1 lub ZF == 1
--------------- ---- ----------
GE , NL Większy lub równy, nie mniej SF == OF
NGE , L Nie większy lub równy, mniej SF ! = OF
G , NLE Większy, nie mniejszy lub równy ZF == 0 i SF == OF
NG , LE Nie większy, mniejszy lub równy ZF == 1 lub SF ! = OF

W przypadku 16 bitów odjęcie 1 od 0 wynosi 65,535 lub -1 zależności od tego, czy użyta jest arytmetyka niepodpisana czy podpisana - ale miejsce docelowe zawiera 0xFFFF obu przypadkach. Znaczenie jest jasne tylko poprzez interpretację kodów warunków. Jeszcze bardziej wymowne jest to, czy 1 jest odejmowane od 0x8000 : w arytmetyki bez znaku, co zmienia jedynie 32,768 w 32,768 32,767 ; natomiast w podpisanej arytmetyki zmienia -32,768 do 32,767 - znacznie bardziej godne uwagi przepełnienie!

Kody warunków są pogrupowane w trzy bloki w tabeli: nieistotne dla znaku, niepodpisane i podpisane. Nazwy wewnątrz dwóch ostatnich bloków używają „Above” i „Below” dla niepodpisanych oraz „Greater” lub „Less” dla podpisanych. Zatem JB byłby „Jump if Below” (niepodpisany), podczas gdy JL byłby „Jump if Less” (podpisany).

Bezpośredni dostęp do FLAGS

Powyższe kody warunków są przydatne do interpretowania predefiniowanych pojęć, ale rzeczywiste bity flagi są również dostępne bezpośrednio z następującymi dwiema instrukcjami:

  • LAHF Załaduj rejestr AH z flagami
  • SAHF Store AH w Flags

Tylko niektóre flagi są kopiowane wraz z tymi instrukcjami. Cały EFLAGS FLAGS / EFLAGS / RFLAGS można zapisać lub przywrócić na stosie:

  • PUSHF / POPF Wciśnij / pop 16-bitowe FLAGS na / ze stosu
  • PUSHFD / POPFD Push / pop 32-bitowe EFLAGS na / ze stosu
  • PUSHFQ / POPFQ Wciśnij / pop 64-bitowe RFLAGS na / ze stosu

Należy pamiętać, że przerwania automatycznie zapisują i przywracają bieżący rejestr [R/E]FLAGS .

Inne flagi

Oprócz flag ALU opisanych powyżej rejestr FLAGS definiuje inne flagi stanu systemu:

  • IF Flaga Przerwania.
    Jest to ustawiane za pomocą instrukcji STI aby globalnie włączać przerwania, i usuwane za pomocą instrukcji CLI aby globalnie wyłączać przerwania.
  • DF Flaga kierunku.
    Operacje pamięć-pamięć, takie jak CMPS i MOVS (w celu porównania i przemieszczania się między lokalizacjami pamięci) automatycznie zwiększają lub zmniejszają rejestry indeksu jako część instrukcji. Flaga DF określa, co się stanie: jeśli zostanie wyczyszczona instrukcją CLD , są one zwiększane; jeśli ustawione za pomocą instrukcji STD , są zmniejszane.
  • TF Flaga pułapki. To jest flaga debugowania. Ustawienie go spowoduje przejście procesora w tryb „jednoetapowy”: po wykonaniu każdej instrukcji wywoła „Single Step Interrupt Handler”, który powinien być obsługiwany przez debugger. Nie ma instrukcji, aby ustawić lub usunąć tę flagę: musisz manipulować bitem, gdy jest on w pamięci.

80286 Flagi

Aby wesprzeć nowe funkcje wielozadaniowości w 80286, Intel dodał dodatkowe flagi do rejestru FLAGS :

  • IOPL Poziom uprawnień we / wy.
    Aby chronić kod wielozadaniowy, niektóre zadania wymagały uprawnień dostępu do portów we / wy, podczas gdy inne musiały być powstrzymywane przed dostępem do nich. Intel wprowadził czteropoziomową skalę przywilejów, przy czym 00 2 jest najbardziej uprzywilejowany, a 11 2 jest najmniejszy. Jeśli IOPL był niższy niż bieżący poziom uprawnień, każda próba dostępu do portów we / wy lub włączenia lub wyłączenia przerwań spowodowałaby ogólny błąd ochrony.
  • NT Zagnieżdżona flaga zadania.
    Ta flaga została ustawiona jeśli jedno zadanie CALL ed innego zadania, co spowodowało przełączenie kontekstu. Flaga set powiedziała procesorowi, aby wykonał zmianę kontekstu z powrotem, gdy wykonano RET .

80386 Flagi

386 potrzebował dodatkowych flag do obsługi dodatkowych funkcji zaprojektowanych w procesorze.

  • RF Flaga wznowienia.
    W `386 dodano rejestry debugowania, które mogą wywoływać debuger na różnych dostępach sprzętowych, takich jak czytanie, zapisywanie lub wykonywanie określonej lokalizacji pamięci. Jednak gdy program obsługi debugowania powróci w celu wykonania instrukcji, dostęp natychmiast ponownie uruchomi procedurę obsługi debugowania! A przynajmniej tak by było, gdyby nie flaga wznowienia, która jest automatycznie ustawiana przy wejściu do modułu obsługi debugowania i automatycznie usuwana po każdej instrukcji. Jeśli ustawiona jest flaga wznowienia, moduł obsługi debugowania nie jest wywoływany.
  • VM Flaga Virtual 8086.
    W celu obsługi starszego kodu 16-bitowego, a także nowszego kodu 32-bitowego, 80386 może uruchamiać 16-bitowe zadania w trybie „Virtual 8086” z pomocą programu wykonawczego Virtual 8086. Flaga VM wskazuje, że to zadanie było wirtualne 8086.

80486 Flagi

Wraz z poprawą architektury Intel, stała się szybsza dzięki takim technologiom, jak pamięci podręczne i wykonywanie super-skalarne. To musiało zoptymalizować dostęp do systemu, przyjmując założenia. Aby kontrolować te założenia, potrzebnych było więcej flag:

  • Flaga kontroli wyrównania AC Architektura x86 zawsze mogła uzyskać dostęp do wielobajtowych wartości pamięci na dowolnej granicy bajtów, w przeciwieństwie do niektórych architektur, które wymagały wyrównania wielkości (wartości 4-bajtowe musiały znajdować się na granicach 4-bajtowych). Było to jednak mniej wydajne, ponieważ do uzyskania dostępu do niezrównanych danych potrzebnych było wiele dostępów do pamięci. Jeśli ustawiono flagę AC , niezaangażowany dostęp zgłosiłby wyjątek, zamiast wykonać kod. W ten sposób kod można ulepszyć podczas programowania przy użyciu zestawu AC , ale wyłączyć kod produkcyjny.

Flagi Pentium

Pentium dodało więcej obsługi wirtualizacji oraz wsparcie dla instrukcji CPUID :

  • VIF Flaga wirtualnego przerwania.
    To jest wirtualna kopia IF tego Zadania - niezależnie od tego, czy to Zadanie chce wyłączyć przerwania, bez faktycznego wpływu na Przerwania Globalne.
  • VIP Flaga wirtualnego przerwania.
    Oznacza to, że przerwanie zostało wirtualnie zablokowane przez VIF , więc gdy Zadanie wykonuje STI można dla niego wywołać przerwanie wirtualne.
  • ID Flaga dozwolona przez CPUID .
    Określa, czy zezwolić temu zadaniu na wykonanie instrukcji CPUID . Monitor wirtualny może go zabronić i „okłamać” żądające Zadanie, jeśli wykona instrukcję.


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow