Sök…


16-bitars register

När Intel definierade den ursprungliga 8086 var det en 16-bitars processor med en 20-bitars adressbuss (se nedan). De definierade 8 allmänna 16-bitarsregister - men gav dem specifika roller för vissa instruktioner:

  • AX Ackumulatorregistret.
    Många opcoder antog antingen detta register eller var snabbare om det anges.
  • DX Dataregistret.
    Detta kombinerades ibland som de höga 16 bitarna med ett 32-bitarsvärde med AX - till exempel som ett resultat av en multiplikation.
  • CX Räknaregistret.
    Detta användes i ett antal looporienterade instruktioner som den implicita räknaren för dessa slingor - till exempel LOOPNE (loop om inte lika) och REP (upprepad flyttning / jämförelse)
  • BX Basregistret.
    Detta kan användas för att indexera basen för en struktur i minnet - inget av ovanstående register kan användas för att direkt indexera i minnet.
  • SI Källindexregistret.
    Detta var det implicita källindexet i minnet för vissa rörelser och jämför operationer.
  • DI Destinationsindexregistret.
    Detta var det implicita destinationsindexet i minnet för vissa flytta och jämföra operationer.
  • SP Stack Pointer-registret.
    Detta är det minst allmänna registret i uppsättningen! Det pekade på den aktuella positionen i stacken, som användes uttryckligen för PUSH och POP operationer, implicit för CALL och RET med subroutines, och mycket implicit under avbrott. Som sådan var det farligt för ditt program att använda det för allt annat!
  • BP Base Pointer-registret.
    När subroutines kallar andra subroutines, innehåller stacken flera "stack frames". BP kan användas för att hålla den aktuella stapelramen, och sedan när en ny subroutin kallades skulle den kunna sparas på stacken, den nya stapelramen skapades och användes, och vid återgång från den inre subroutinen kunde det gamla stapelramvärdet återställas .

Anmärkningar:

  1. De tre första registren kan inte användas för indexering i minnet.

  2. BX , SI och DI standardindex i det aktuella datasegmentet (se nedan).

     MOV    AX, [BX+5]     ; Point into Data Segment
     MOV    AX, ES:[DI+5]  ; Override into Extra Segment
    
  3. DI , när den används i minne-till-minne-operationer som MOVS och CMPS , använder endast Extra-segmentet (se nedan). Detta kan inte åsidosättas.

  4. SP och BP använder stapelsegmentet (se nedan) som standard.

32-bitars register

När Intel tillverkade 80386 uppgraderade de från en 16-bitars processor till en 32-bitars. 32-bitarsbehandling innebär två saker: både data som manipulerades var 32-bitars och minnesadresserna som åtkom var 32-bitars. För att göra detta, men fortfarande förbli kompatibla med sina tidigare processorer, introducerade de helt nya lägen för processorn. Det var antingen i 16-bitarsläge eller 32-bitarsläge - men du kan åsidosätta det här läget på en instruktionsbaserad instruktion för antingen data, adressering eller båda!

Först av allt var de tvungna att definiera 32-bitars register. De gjorde detta genom att helt enkelt utöka de befintliga åtta från 16 bitar till 32 bitar och ge dem "utökade" namn med ett E prefix: EAX , EBX , ECX , EDX , ESI , EDI , EBP och ESP . De nedre 16 bitarna av dessa register var desamma som tidigare, men de övre halvorna av registren var tillgängliga för 32-bitars operationer såsom ADD och CMP . De övre halvorna var inte separat tillgängliga, som de hade gjort med 8-bitarsregistren.

Processorn måste ha separata 16-bitars- och 32-bitarslägen eftersom Intel använde samma opcoder för många av operationerna: CMP AX,DX i 16-bitarsläge och CMP EAX,EDX i 32-bitarsläge hade exakt samma opcoder ! Detta innebar att samma kod INTE kunde köras i något av lägena:

Opoden för "Flytta omedelbart till AX " är 0xB8 , följt av två byte med det omedelbara värdet: 0xB8 0x12 0x34

Opoden för "Flytta omedelbart till EAX " är 0xB8 , följt av fyra byte med det omedelbara värdet: 0xB8 0x12 0x34 0x56 0x78

Så assember måste veta vilket läge processorn är i när koden körs, så att den vet att avge rätt antal byte.

8-bitars register

De första fyra 16-bitarsregistrema kan ha sina övre och nedre halva byte åtkomst direkt som sina egna register:

  • AH och AL är de höga och låga halvorna i AX registret.
  • BH och BL är de höga och låga halvorna i BX registret.
  • CH och CL är de höga och låga halvorna i CX registret.
  • DH och DL är de höga och låga halvorna i DX registret.

Observera att detta innebär att förändring av AH eller AL omedelbart kommer att förändra AX också! Observera också att alla operationer i ett 8-bitarsregister inte kunde påverka dess "partner" - att AL ökar så att den överflödade från 0xFF till 0x00 skulle inte förändra AH .

64-bitars-register har också 8-bitarsversioner som representerar deras lägre byte:

  • SIL för RSI
  • DIL för RDI
  • BPL för RBP
  • SPL för RSP

Detsamma gäller för register R8 och med R15 : deras respektive nedre R8B heter R8B - R15B .

Segmentregister

segmente~~POS=TRUNC

När Intel utformade den ursprungliga 8086 fanns det redan ett antal 8-bitars processorer som hade 16-bitars kapacitet - men de ville producera en riktig 16-bitars processor. De ville också producera något bättre och mer kapabelt än vad som redan fanns där ute, så de ville ha tillgång till mer än maximalt 65 536 byte minne implicit av 16-bitars adressregister.

Original segmentregister

Så de implementerade idén om "Segment" - ett 64 kilobyte minnesblock indexerat av 16-bitars adressregister - som kan baseras på nytt för att adressera olika områden i det totala minnet. För att hålla dessa segmentbaser inkluderade de segmentregister:

  • CS Kodsegmentet register.
    Detta håller segmentet av koden som för närvarande körs, indexerat av det implicita IP (Instruction Pointer) -registret.
  • DS Datasegmentregistret.
    Detta håller standardsegmentet för data som manipuleras av programmet.
  • ES Extra-segmentet.
    Detta har ett andra datasegment för samtidig datafunktioner över hela minnet.
  • SS Stack-segmentregistret.
    Detta håller det segment av minnet som har den aktuella stacken.

Segmentstorlek?

Segmentregistrerna kan vara av alla storlekar, men genom att göra dem 16 bitar brett gjorde det lätt att samverka med de andra registerna. Nästa fråga var: ska segmenten överlappa varandra, och i så fall hur mycket? Svaret på den frågan skulle diktera den totala minnesstorleken som kan nås.

Om det inte fanns någon överlappning alls skulle adressutrymmet vara 32 bitar - 4 gigabyte - en helt ojämn storlek vid den tiden! En mer "naturlig" överlappning av 8 bitar skulle ge ett 24-bitars adressutrymme, eller 16 megabyte. I slutändan beslutade Intel att spara ytterligare fyra adressstift på processorn genom att göra adressutrymmet 1 megabyte med en 12-bitars överlappning - de ansåg detta vara tillräckligt stort för tiden!

Fler segmentregister!

När Intel utformade 80386 insåg de att den befintliga sviten med 4 segmentregister inte var tillräckligt för komplexiteten i program som de ville att den skulle kunna stödja. Så de lägger till ytterligare två:

  • FS The Far Segment-registret
  • GS Det globala segmentregistret

Dessa nya segmentregister hade inga processorer som användes: de var bara tillgängliga för vad programmeraren ville ha.

Vissa säger att namnen valdes för att helt enkelt fortsätta C , D , E temat i den befintliga uppsättningen ...

64-bitars register

AMD är en processortillverkare som hade licensierat designen av 80386 från Intel för att producera kompatibla - men konkurrerande - versioner. De gjorde interna förändringar i designen för att förbättra genomströmningen eller andra förbättringar av designen, medan de fortfarande kunde köra samma program.

För en av Intel, de kom med 64-bitars tillägg till Intel 32-bitars design och producerade det första 64-bitars chip som fortfarande kunde köra 32-bitars x86-kod. Intel slutade efter AMDs design i sina versioner av 64-bitarsarkitekturen.

64-bitarsdesignen gjorde ett antal ändringar i registermängden, medan de fortfarande var bakåtkompatibla:

  • De befintliga allmänna registren utvidgades till 64 bitar och namngavs med ett R prefix: RAX , RBX , RCX , RDX , RSI , RDI , RBP och RSP .

    Återigen var de nedre halvorna av dessa register samma E referensregister som tidigare, och de övre halvorna kunde inte nås oberoende.

  • Ytterligare 8 64-bitars register lades till och namngavs utan bara numrerades: R8 , R9 , R10 , R11 , R12 , R13 , R14 och R15 .
    • Den 32-bitars låga halvan av dessa register är R8D till R15D (D för DWORD som vanligt).
    • De lägsta 16 bitarna av dessa register kan nås genom att eftertrycka ett W till registernamnet: R8W till R15W .
  • De lägsta 8 bitarna av alla 16 register kan nu nås:
    • Den traditionella AL , BL , CL och DL ;
    • De låga bytena i (traditionellt) pekarregistret: SIL , DIL , BPL och SPL ;
    • Och de låga bytena från de 8 nya registren: R8B till R15B .
    • AH , BH , CH och DH är emellertid otillgängliga i instruktioner som använder ett REX-prefix (för 64 bit operandstorlek, eller för att komma åt R8-R15, eller för att få åtkomst till SIL , DIL , BPL eller SPL ). Med ett REX-prefix betyder maskinkodets bitmönster som brukade betyda AH istället SPL , och så vidare. Se tabell 3-1 i Intels instruktionshandbok (volym 2).

Att skriva till ett 32-bitars register nollar alltid de övre 32 bitarna i fullbreddregistret, till skillnad från att skriva till ett 8 eller 16-bitarsregister (som smälter samman med det gamla värdet, vilket är ett extra beroende för exekvering av ordningen ).

Flaggor register

När x86 Arithmetic Logic Unit (ALU) utför operationer som NOT och ADD , flaggas resultaten av dessa operationer ("blev noll", "överflöde", "blev negativ") i ett speciellt 16-bitars FLAGS register. 32-bitars processorer uppgraderade detta till 32 bitar och kallade det EFLAGS , medan 64-bitars processorer uppgraderade detta till 64 bitar och kallade det RFLAGS .

Konditionskoder

Men oavsett namn är registret inte direkt tillgängligt (förutom några instruktioner - se nedan). I stället hänvisas till enskilda flaggor i vissa instruktioner, till exempel villkorad hopp eller villkorlig uppsättning, känd som Jcc och SETcc där cc betyder "villkorskod" och refererar till följande tabell:

Tillståndskod namn Definition
E , Z Lika, noll ZF == 1
NE , NZ Inte lika, inte noll ZF == 0
O Svämma över OF == 1
NO Inget överflöde OF == 0
S Signerad SF == 1
NS Inte undertecknad SF == 0
P Paritet PF == 1
NP Ingen paritet PF == 0
-------------- ---- ----------
C , B , NAE Bär nedanför, inte över eller lika CF == 1
NC , NB , AE Ingen bärning, inte under, ovan eller lika CF == 0
A , NBE Ovan, inte under eller lika CF == 0 och ZF == 0
NA , BE Inte ovan, under eller lika CF == 1 eller ZF == 1
--------------- ---- ----------
GE , NL Större eller lika, inte mindre SF == OF
NGE , L Inte större eller lika, mindre SF ! = OF
G , NLE Större, inte mindre eller lika ZF == 0 och SF == OF
NG , LE Inte större, mindre eller lika ZF == 1 eller SF ! = OF

I 16 bitar är subtraktion av 1 från 0 antingen 65,535 eller -1 beroende på om osignerad eller signerad aritmetik används - men destinationen har 0xFFFF alla fall. Det är bara genom att tolka villkorskoderna att betydelsen är tydlig. Det är ännu mer uppenbart om 1 dras från 0x8000 : i osignerad aritmetik förändras det bara 32,768 till 32,767 ; medan det i signerad aritmetik förändras -32,768 till 32,767 - ett mycket mer anmärkningsvärt överflöde!

Betingelsekoderna grupperas i tre block i tabellen: tecken-irrelevant, osignerad och signerad. Namngivningen inuti de två senare blocken använder "Ovan" och "Nedan" för osignerade och "Större" eller "Mindre" för signerade. Så JB skulle vara "Jump if below" (osignerad), medan JL skulle vara "Jump if Less" (signerad).

Åtkomst till FLAGS direkt

Ovanstående villkorskoder är användbara för att tolka fördefinierade koncept, men de faktiska flaggbitarna finns också tillgängliga direkt med följande två instruktioner:

  • LAHF Ladda AH register med flaggor
  • SAHF Store AH register i flaggor

Endast vissa flaggor kopieras över med dessa instruktioner. Hela FLAGS / EFLAGS / RFLAGS registret kan sparas eller återställas på bunten:

  • PUSHF / POPF Tryck / pop 16-bitars FLAGS till / från stacken
  • PUSHFD / POPFD Tryck / pop 32-bitars EFLAGS till / från stacken
  • PUSHFQ / POPFQ Tryck / pop 64-bitars RFLAGS till / från stacken

Observera att avbrott sparar och återställer det nuvarande [R/E]FLAGS registret automatiskt.

Andra flaggor

Förutom de ovan FLAGS ALU-flaggorna definierar FLAGS registret andra systemstatliga flaggor:

  • IF Avbrytande flaggan.
    Detta ställs in med STI instruktionen för att globalt möjliggöra avbrott och rensas med CLI instruktionen för att globalt avaktivera avbrott.
  • DF Riktningsflaggan.
    Minne-till-minne-operationer som CMPS och MOVS (för att jämföra och flytta mellan minnesplatser) ökar eller minskar indexregistrerna automatiskt som en del av instruktionen. DF flaggan dikterar vilken som händer: om den rensas med CLD instruktionen ökas de; om de ställs in med STD instruktionen, dekrementeras.
  • TF Trap Flag. Detta är en felsökningsflagg. Om du ställer in den kommer processorn i "enkelsteg" -läge: efter att varje instruktion har utförts kommer den att ringa "Single Step Interrupt Handler", som förväntas hanteras av en felsökare. Det finns inga instruktioner för att ställa in eller rensa denna flagga: du måste manipulera biten medan den är i minnet.

80286 Flaggor

För att stödja de nya multitasking-anläggningarna i 80286 har Intel lagt till FLAGS flaggor till FLAGS registret:

  • IOPL I / O-privilegienivå.
    För att skydda multitaskingskod behövde vissa uppgifter privilegier för att få åtkomst till I / O-portar, medan andra måste stoppas från att komma åt dem. Intel introducerade en fyra nivåer Privilege skala, där 00 2 var mest privilegierade och 11 2 som minst. Om IOPL var lägre än den nuvarande behörighetsnivån skulle alla försök att komma åt I / O-portar, eller aktivera eller inaktivera interrups, i stället orsaka ett allmänt skyddsfel.
  • NT Nested Task flagga.
    Denna flagga ställdes in om en uppgift CALL redigerade en annan uppgift, vilket orsakade en kontextomkopplare. Den inställda flaggan berättade för processorn att göra en kontextomkopplare när RET kördes.

80386 Flaggor

386 behövde extra flaggor för att stödja extra funktioner designade i processorn.

  • RF Resume Flag.
    386 tillagda felsökningsregister, vilket kan påkalla felsökaren på olika hårdvarutillgångar som att läsa, skriva eller köra en viss memerplats. Men när felsökningshanteraren återvände för att utföra instruktionen skulle åtkomsten omedelbart återkalla felsökningshanteraren! Eller åtminstone skulle det göra om det inte var för återupptagningsflaggan, som automatiskt ställs in vid inträde i felsökningshanteraren och rensas automatiskt efter varje instruktion. Om Resume Flag är inställt startas inte felsökningshanteraren.
  • VM Den virtuella 8086-flaggan.
    För att stödja äldre 16-bitars kod såväl som nyare 32-bitars kod kan 80386 köra 16-bitarsuppgifter i ett "Virtual 8086" -läge med hjälp av en Virtual 8086-verkställande. VM flaggan indikerade att denna uppgift var en virtuell 8086-uppgift.

80486 Flaggor

När Intel-arkitekturen förbättrades blev det snabbare genom teknik som cachar och superskalär exekvering. Det måste optimera åtkomsten till systemet genom att göra antaganden. För att kontrollera dessa antaganden behövdes fler flaggor:

  • AC Alignment Kontrollera flaggan x86-arkitekturen kan alltid komma åt minnesvärden för flera byte på valfri byte-gräns, till skillnad från vissa arkitekturer som krävde att de skulle vara i linje med storleken (4-byte-värden måste vara på 4-byte-gränser). Men det var mindre effektivt att göra det, eftersom flera minnesåtkomst behövdes för att få åtkomst till ojusterad data. Om AC flaggan var inställd, skulle en ojusterad åtkomst höja ett undantag snarare än att köra koden. På så sätt kan kod förbättras under utveckling med AC set, men stängs av för produktionskod.

Pentium-flaggor

Pentium har lagt till mer stöd för virtualisering, plus stöd för CPUID instruktionen:

  • VIF The Virtual Interrupt Flag.
    Detta är en virtuell kopia av denna uppgifts IF - oavsett om denna uppgift vill inaktivera avbrott utan att påverka Globala avbrott eller inte.
  • VIP Den flagga som VIP virtuellt avbrott.
    Detta indikerar att ett avbrott nästan blockerades av VIF , så när uppgiften gör en STI ett virtuellt avbrott höjas för det.
  • ID CPUID tillåtna flaggan.
    Huruvida detta uppdrag ska utföra CPUID instruktionen eller inte. En virtuell bildskärm kan avvisa den och "ljuga" till den begärande uppgiften om den kör instruktionen.


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow