Registrul steagului

Registrul flag sau  cuvântul de stare procesor (CSP) este un registru specializat care reflectă starea curentă a procesorului.

arhitectura x86

În microprocesoarele Intel 8086 , se numește FLAGS și este pe 16 biți. Registrele extinse EFLAGS și RFLAGS, introduse în arhitecturile IA-32 ( procesoare 80386 ) și x86-64 , sunt pe 32 de biți și, respectiv, pe 64 de biți. Registrele extinse sunt compatibile cu invers.

Registrul de steaguri conține un grup de steaguri de stare, un steaguri de control și un grup de steaguri de sistem [1] :

Registrul steag Intel x86
Un pic, nu. Desemnare Nume Descriere tip steag Când este introdus
STRAPURI
0 CF Purtați steagul Purtați steagul Stat
unu unu Rezervat
2 PF Steagul de paritate Steagul de paritate Stat
3 0 Rezervat
patru AF Steagul de transport auxiliar Steagul de transport auxiliar Stat
5 0 Rezervat
6 ZF Steagul Zero Steagul Zero Stat
7 SF Semnează Steagul semn steagul Stat
opt TF Drapelul capcanei Urmărire steag (pas) Sistemică
9 DACĂ Indicatorul de activare a întreruperii Indicator de activare întrerupere Sistemică
zece D.F. Steagul de direcție Steagul de direcție Administrator
unsprezece DE Steagul de preaplin steag de revărsare Stat
12 IOPL Nivel de privilegii I/O Nivel de prioritate I/O Sistemică 80286
13
paisprezece NT Sarcină imbricată Steagul de imbricare a sarcinilor Sistemică 80286
cincisprezece 0 Rezervat
steaguri
16 RF Reluați steag Reluați steag Sistemică 80386
17 VM Modul Virtual-8086 8086 modul procesor virtual Sistemică 80386
optsprezece AC Verificarea alinierii Verificarea alinierii Sistemică 80486SX _
19 VIF Steagul de întrerupere virtuală Indicator de activare a întreruperii virtuale Sistemică Pentium
douăzeci VIP Întreruperea virtuală în așteptare Întreruperea virtuală în așteptare Sistemică Pentium
21 ID Steagul ID Verificarea disponibilității instrucțiunilorCPUID Sistemică 80486 târziu [2]
22 0 rezervat
31
RFLAGS
32 0 rezervat
63

Valoarea unor steaguri din registrul de steaguri poate fi schimbată direct, folosind instrucțiuni speciale (de exemplu, CLDpentru a reseta steagul de direcție), dar nu există instrucțiuni care să vă permită să accesați (verificați sau modificați) registrul de steaguri ca un registru obișnuit. . Cu toate acestea, este posibil să salvați registrul de steag în stivă sau în registrul (E)AX și să restaurați registrul de steag din acestea folosind instrucțiunile LAHF, SAHF, PUSHF, PUSHFD, POPFși POPFD.

Atunci când o sarcină este suspendată (folosind capacitățile multitasking ale procesorului), procesorul salvează automat valoarea steagului de registru în TSS (segmentul de stare a sarcinii), atunci când este activată o nouă sarcină, procesorul încarcă registrul de steag din TSS. a noii sarcini.

Când un handler de întrerupere sau un handler de excepții este activat , procesorul salvează automat valoarea registrului de steaguri pe stiva curentă.

Steaguri de stat active

Indicatoarele de stare (biții 0, 2, 4, 6, 7 și 11) reflectă rezultatul executării instrucțiunilor aritmetice precum ADD, SUB, MUL, DIV.

Dintre steaguri listate, numai steagul CF poate fi schimbat direct cu instrucțiunile STCși . De asemenea, instrucțiunile de biți ( , , și ) copiază bitul specificat în flag-ul CF. CLCCMCBTBTSBTRBTC

Indicatoarele de stare permit aceleiași instrucțiuni aritmetice să producă un rezultat de trei tipuri diferite: întreg fără semn, cu semn și zecimal codificat binar (BCD). Dacă rezultatul este considerat un număr nesemnat, atunci indicatorul CF arată condiția de depășire (carry sau orrow), pentru un rezultat semnat (în complement a doi ) carry sau împrumut arată flag OF, iar pentru rezultatul BCD, carry/ împrumut arată steagul AF. Indicatorul SF reflectă semnul unui rezultat semnat, indicatorul ZF reflectă atât un rezultat nesemnat, cât și un rezultat nul semnat.

În aritmetica numerelor întregi lungi, indicatorul CF este folosit împreună cu instrucțiunile de adăugare cu transport ( ADC) și scădere cu împrumut ( SBB) pentru a propaga o transportare sau împrumut de la un bit calculat al unui număr lung la altul.

Instrucțiuni de salt condiționat (săriți la condiția cc  - de exemplu, pentru a sări dacă rezultatul este diferit de zero), (setați valoarea octetului rezultat în funcție de condiția cc ), (bucla) și (copie condiționată) folosesc unul sau mai multe semnalizatoare de stare pentru a verifica termenii. De exemplu, instrucțiunea de salt (săriți dacă este mai mic sau egal - săriți dacă „mai mic sau egal cu”, ≤) verifică condiția „ZF=1 sau SF ≠ OF”. JccJNZSETccLOOPccCMOVccJLE

Steagul PF a fost introdus pentru compatibilitate cu alte arhitecturi de microprocesoare și este rareori folosit în scopul propus. Este mai obișnuit să-l folosești împreună cu alte steaguri de stare în aritmetica în virgulă mobilă [3] : instrucțiunile de comparare ( FCOM, FCOMPetc.) din coprocesorul matematic setează steaguri de condiție C0, C1, C2 și C3, iar aceste steaguri poate fi copiat în registrul de semnalizare. Pentru a face acest lucru, se recomandă utilizarea unei instrucțiuni FSTSW AXde stocare a cuvântului de stare a coprocesorului în registrul AX și a unei instrucțiuni SAHFpentru a copia ulterior conținutul registrului AH în cei 8 biți inferiori ai registrului flag [4] , în timp ce C0 intră în steagul CF, C2 în PF și C3 în ZF. Indicatorul C2 este setat, de exemplu, în cazul argumentelor incomparabile (NaN sau format neacceptat) în instrucțiunea de comparare FUCOM.

Steagul de control

Indicatorul de direcție (DF, bitul 10 din registrul flag) controlează instrucțiunile șirului ( MOVS, CMPS, SCAS, LODSși STOS): setarea steagului determină scăderea adreselor (procesează liniile de la adresele înalte la cele joase), zero face ca adresele să crească. Instrucțiunile STDși CLDsetează și, respectiv, resetați indicatorul DF.

Indicatoarele de sistem și câmpul IOPL

Indicatoarele de sistem și câmpul IOPL controlează mediul de operare și nu sunt destinate a fi utilizate în programele de aplicație.

Identificarea procesorului

În versiunile ulterioare ale procesorului 80486, a apărut instrucțiunea CPUID , care vă permite să identificați procesorul pe care rulează programul. La procesoarele anterioare, pentru identificare, este necesar să se analizeze comportamentul instrucțiunilor, inclusiv registrul flag.

De exemplu, pe procesoarele 8086 și 80186 , biții 12-15 ai registrului de steag sunt întotdeauna setați, pe procesoarele 80286 și ulterioare, biții 12-14 conțin câmpul IOPL și steag-ul NT și sunt întotdeauna șterși în modul real . Acest lucru face posibilă distingerea între procesoarele 808x/8018x, 80286 și 80386 (și mai noi) în codul de 16 biți:

Cod de limbaj de asamblare MASM pentru a distinge între procesoarele 8086 - 80386 pushf ; (Păstrează starea inițială a registrului de pavilion) pushf ; Copy flag case... pop ax ; ...a inregistra AX xor ah , 11110000 b ; Schimbați valoarea push ax de 4 biți ; Copiați registrul AX popf ; ...la registrul steag pushf ; Copiați cazul steagului... pop bx ; ... pentru a înregistra BX popf ; (Resetează registrul steagului) xor ah , bh ; AH=0 (biții din registrul flag nu au fost modificați) → 808x-80286, în caz contrar 80386+ și bh , 11110000 b ; BH=F0h (seți toți cei 4 biți) → 808x/8018x, 0 → 80286

De asemenea, indicatorul AC (bit 18) introdus în 80486 este întotdeauna șters în 80386, ceea ce face posibilă diferența între aceste procesoare:

Cod de limbaj de asamblare MASM pentru a distinge între procesoarele 80386 și 80486 și sp , nu 3 ; Aliniați stiva astfel încât să nu existe erori de aliniere la accesarea acestuia pushfd ; (Păstrează starea inițială a registrului pavilionului) pushfd ; Copy flag case... pop eax ; ...a inregistra EAX xor eax , 40000 h ; Schimbați valoarea bitului 18 (steagul AC) push eax ; Copiați registrul EAX popfd ; ...la registrul steag pushfd ; Copiați steaguri de registru... pop ecx ; ...la registrul ECX popfd ; (Resetează registrul de steag) xor eax , ecx ; EAX=0 (bit în registrul flag nu a fost modificat) → 80386

În mod similar, în modelele 80486 mai vechi în care instrucțiunea CPUIDnu a fost încă introdusă, indicatorul ID (bit 21) este întotdeauna șters, ceea ce permite identificarea procesoarelor 80386 și a modelelor 80486 mai vechi:

Codul limbajului de asamblare MASM pentru a defini vechiul 80486 pushfd ; (Păstrează starea inițială a registrului pavilionului) pushfd ; Copy flag case... pop eax ; ...to EAX register mov ecx , eax ; ...și în registrul ECX sau eax , 200000 h ; Setați bitul 21 (steagul ID) push eax ; Copiați registrul EAX popfd ; ...la registrul steag pushfd ; Copy flag case... pop eax ; ...la registrul EAX popfd ; (Resetează registrul de steag) xor eax , ecx ; EAX=0 (bit în registrul flag nu este setat) → 80386/vechi 80486

Vezi și

Note

  1. 3.4.3. Registru EFLAGS // Manualul dezvoltatorului de software pentru arhitectură Intel IA-32. - Intel , 2004. - T. 1: Arhitectura de bază . Număr comandă: 253665-013
  2. 1 2 Instrucțiunea CPUIDa fost adăugată în versiunile ulterioare ale procesorului 80486 și procesorului Pentium. Consultați: CPUID - Identificare CPU // Manualul dezvoltatorului de software pentru arhitectură Intel IA-32. - Intel , 2004. - V. 2A: Referință setului de instrucțiuni, AM . Număr comandă: 253666-013
  3. 8.1.3. Branching and Conditional Moves on Condition Codes // Manualul pentru dezvoltatori de software pentru arhitectură Intel IA-32. - Intel , 2004. - Vol. 1: Arhitectura de bază. Număr comandă: 253665-013
  4. În arhitectura P6 s- au introdus instrucțiuni etc. FCOMI, FCOMIPcare, în urma comparației, stabilesc direct steagurile în registrul steagurilor. Anterior, acest lucru nu era posibil, deoarece coprocesorul a fost implementat pe un cip separat și abia începând de la 80486DX, coprocesorul a început să fie încorporat în procesor.