RFLAGS

Registrul de steaguri de registru - menționat și steaguri de registru - este registrul de stat al procesoarelor familia x86-64 (64 de biți). Este compatibil cu registrele EFLAGS și FLAGS moștenite din familiile x86 (32 biți) și anterioare (16 biți).

Vă permite să setați și să cunoașteți starea procesorului în orice moment datorită diferiților biți care îl compun. Acest registru face astfel posibilă obținerea în orice moment a stării rezultate dintr-o instrucțiune executată de procesor, majoritatea instrucțiunilor procesorelor x86 afectând acest registru.

Starea diferiților biți (steagurile) din registrul RFLAGS permite procesorului să ia decizii, de exemplu la nivelul ramurilor condiționate (salturi și bucle) sau după o operație aritmetică (carry sau overflow etc.).

Prezentare generală a registrului RFLAGS

Registrul RFLAGS este format din 64 de biți și este disponibil numai pe procesoarele pe 64 de biți ( x86-64 ). Cu toate acestea, este compatibil înapoi cu registrele EFLAGS (disponibile pe procesoare x86 pe 32 de biți) și FLAGS (disponibile pe procesoare pe 16 și 32 de biți). Se compune după cum urmează:

Când rulați în modul de compatibilitate pe 32 de biți (când procesorul pe 64 de biți execută cod pe 32 de biți) sunt accesibile doar EFLAGS și FLAGS.

Cei 64 de biți ai registrului RFLAGS și numele steagurilor sale.
RFLAGS
Biți 63..32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13..12 11 10 9 8 7 6 5 4 3 2 1 0
Steaguri - - - - - - - - - - - ID VIP VIF AC VM RF 0 NT IOPL DE DF DACĂ TF SF ZF 0 AF 0 PF 1 CF

Notă  : biții 63 la 32, 31 la 22, 15, 5, 3, 1 (în gri pe masă) sunt biți rezervați, utilizarea și funcționarea lor este necunoscută. Biții 15, 5, 3, 1 au o valoare fixă ​​dată în tabelul de mai sus.

Se spune că un steag este înarmat când este la 1 și dezarmat când este la 0.

Categorii de semnalizare

Există trei categorii diferite de steaguri în registrul RFLAGS.

Steaguri de stat

Biții 0, 2, 4, 6, 7 și 11 din registrul RFLAGS indică rezultatele operațiilor aritmetice rezultate din instrucțiuni precum ADD, DIV, MUL, SUB etc.

Instrucțiuni afectate de steagurile de stare

Următoarele declarații condiționale utilizează unul sau mai multe dintre semnalizatoarele de stare ca o condiție pentru ramuri condiționate, armare de octeți sau condiții de sfârșit de buclă:

  • J cc  : Salt la codul de stare cc (de exemplu instrucțiuni JE, JO, JNC etc.).
  • SET cc  : setați codul de stare cc (de exemplu instrucțiunile SETNE, SETNO etc.).
  • LOOP cc  : Buclați codul de stare cc (de exemplu instrucțiunile LOOPE, LOOPNZ etc.)
  • CMOV cc  : mutarea condiționată a codului de stare cc (de exemplu instrucțiunile CMOVNZ, CMOVNO etc.)
Instrucțiuni pentru modificarea steagurilor de stare

Numai steagul CF poate fi schimbat direct prin anumite instrucțiuni. Aceste instrucțiuni sunt după cum urmează:

  • CMC (pentru C o m plement C arry Flag ): Reverse starea pavilion transporta.
  • CLC (pentru Cl ureche C arry Flag ): dezarmeaza pavilion transporta.
  • STC (pentru S e t C Arry Flag ): Înarmează steagul de transport.

Următoarele instrucțiuni bit-bit pot copia un bit specific direct în steagul CF  :

  • BT
  • BTC
  • BTR
  • BTC

Steagul de control

Bitul 10 al registrului RFLAGS este singurul semnalizator de control (numit și semnalizator de direcție).

  • DF (bit 10) Direction Flag : Acest flag este utilizat împreună cu instrucțiunile care operează pe șiruri. Când este setat semnalizatorul DF, adresele șirurilor de caractere sunt automat decrementate (mergând astfel de la cele mai mari adrese la cele mai mici adrese). Când semnalizatorul este dezarmat, adresele șirurilor de caractere sunt incrementate automat (mergând de la cele mai mici adrese la cele mai mari adrese). Nu există niciun rezultat al operației care să armeze sau să dezarmeze semnalizatorul de direcție. Doar două instrucțiuni vă permit să specificați în mod explicit starea acestuia.
Instrucțiuni afectate de steagul de control

Instrucțiunile care lucrează pe șiruri sau octeți sunt singurele instrucțiuni afectate de semnalizatorul de direcție. Aceste instrucțiuni sunt după cum urmează:

  • CMPS (pentru C o mp sunt S trings ): Compară două șiruri.
  • LODS (pentru Lo a d S tring ): Încarcă următorul cuvânt al lanțului în registrul EAX.
  • MOVS (pentru Mov e S trings ): Transferă un cuvânt de la canalul sursă la canalul țintă.
  • SCAS (pentru Sca n S tring ): Compară cuvântul din registrul EAX cu cuvântul următor din șir.
  • STOS (pentru Sto re S tring ): Stochează cuvântul din registrul EAX din cuvântul următor al lanțului.

Dimensiunea cuvântului folosit de aceste instrucțiuni este un număr fix de octeți în funcție de sufixul utilizat (B pentru B yte = 1 octeț , W pentru W ord = 2 octeți, D pentru D cuvânt dublu = 4 octeți ...).

Instrucțiuni pentru schimbarea steagului de control

Instrucțiunile pentru schimbarea directă a indicatorului de direcție sunt după cum urmează:

  • CLD (pentru Cl ureche D irection Flag ): dezarmeaza pavilion direcție.
  • STD (standard pentru pavilionul S e t D irectorat ): pavilion de direcție a armelor.

Semnalizatoare de sistem

Semnalizatoarele sistemului de registru RFLAGS sunt controlate de operațiunile sistemului de operare sau de monitorizare a sistemului. În mod normal, un program de aplicație nu ar trebui să modifice starea acestor semnalizatoare. Biții 12 și 13 nu sunt considerați ca două semnalizatoare, ci ca un câmp pe 2 biți (câmpul IOPL).

  • TF (bit 8) Trap Flag : Când este setat, acest flag permite depanarea în modul pas cu pas, adică instrucțiune cu instrucțiune. Când este dezarmat, modul de pas este inoperant (funcționare normală).
  • IF (bit 9) Indicator de întrerupere : Acest indicator controlează modul în care procesorul răspunde la solicitările de întrerupere care pot fi mascate (adică dezactivabile). Când este înarmat, procesorul poate răspunde la toate întreruperile, în caz contrar (dacă semnalizatorul este dezarmat), procesorul va putea răspunde numai la întreruperile care nu pot fi mascate.
  • IOPL (biții 12 și 13) Câmpul nivelului de privilegiu de intrare / ieșire : Acest câmp indică nivelul de privilegiu de intrare / ieșire (I / O) al programului sau sarcinii curente. Nivelul actual de privilegiu al programului sau activității curente trebuie să fie egal sau mai mic decât nivelul privilegiului I / O pentru a accesa spațiul de adrese. Acest câmp poate fi modificat numai cu un nivel de privilegiu egal cu 0 (cel mai înalt nivel de privilegiu). Acest concept de niveluri de privilegii este implementat prin inele de protecție .
  • NT (bit 14) Semnalizare sarcină imbricată : Acest semnalizator controlează secvențierea sarcinilor întrerupte și apelate. Astfel indică, atunci când este înarmat, dacă sarcina curentă este legată de o sarcină părinte (sarcina care a fost executată anterior) prin instrucțiunea CALL sau printr-o întrerupere. Când este dezarmat, acest indicator indică pur și simplu că sarcina curentă nu are sarcină părinte.
  • RF (bit 16) Resume Flag : Acest flag controlează răspunsul procesorului la excepțiile de depanare. În special, asigură că depanarea pas cu pas (vezi pavilion TF) are loc o singură dată pe instrucțiune.
  • VM (bit 17) Virtual-8086 mode Flag : Când acest flag este armat, procesorul este în modul virtual 8086. Când este dezarmat, procesorul revine la modul protejat.
  • AC (bit 18) Steag de verificare a alinierii : Acest steag, atunci când este setat, oferă o verificare a alinierii referințelor de memorie. Când este dezarmat, nu se efectuează nici o verificare a alinierii. Acest steag necesită ca bitul AM al registrului de control CR0 să fie setat împreună.
  • VIF (bit 19) Steag de întrerupere virtuală : Acest steag este o imagine virtuală a steagului IF. Este utilizat împreună cu steagul VIP (bit 20).
  • VIP (bit 20) Întrerupere virtuală în așteptare : Când este setată, această semnalizare indică faptul că o întrerupere este în așteptare. Când este dezarmat, acest indicator indică faptul că nu există nicio întrerupere. Numai programele pot înarma sau dezarma acest flag, procesorul îl citește doar. A se utiliza împreună cu steagul VIF (bit 19).
  • ID (bit 21) Steag de identificare : Dacă un program are capacitatea de a înarma sau dezarma acest steag, acesta indică faptul că procesorul acceptă utilizarea instrucțiunii CPUID.
Instrucțiuni afectate de semnalizatoarele de sistem

În general, semnalizatoarele de sistem nu modifică modul în care sunt executate instrucțiunile, ci afectează doar funcționarea generală a sistemului de operare. Cu toate acestea, câmpul IOPL poate permite, de exemplu, utilizarea anumitor instrucțiuni la diferite niveluri de protecție.

Instrucțiuni pentru modificarea semnalizatoarelor de sistem

Numai câmpul IOPL (biții 12 și 13) poate fi atribuit direct prin instrucțiuni. Aceste instrucțiuni pot fi utilizate numai dacă nivelul de privilegiu este cel mai înalt (nivelul 0):

  • IRET
  • POPF

Instrucțiuni care afectează RFLAGS

În plus față de instrucțiunile pentru armarea sau dezarmarea unui singur bit (sau chiar două pentru câmpul IOPL) din registrul RFLAGS, unele instrucțiuni permit citirea sau chiar scrierea totală sau parțială a registrului RFLAGS. Aceste instrucțiuni sunt:

  • LAHF: biții de la 0 la 7 din RFLAGS sunt introduși în registrul AH (operația de citire).
  • SAHF: conținutul registrului AH este plasat în biții 0 la 7 din RFLAGS (operație de scriere).
  • POPF: cuvântul de 16 biți aflat în prezent în partea de sus a stivei este plasat în biții 0 la 15 din RFLAGS (operație de scriere) - în modul pe 64 de biți, instrucțiunea necesită prefixul dimensiunii operandului (66h) pentru a funcționa pe 16 biți.
  • POPFD: Cuvântul dublu (32 de biți) în prezent în partea de sus a stivei este plasat în RFLAGS (operație de scriere) - în modul pe 64 de biți, instrucțiunea se comportă ca POPFQ.
  • POPFQ: Cuvântul cvadruplu (64 biți) aflat în prezent în partea de sus a stivei este plasat în RFLAGS (operație de scriere).
  • PUSHF: biții de la 0 la 15 din RFLAGS sunt împinși pe stivă (operație de citire) - în modul pe 64 de biți, instrucțiunea necesită prefixul dimensiunii operatorului (66h) pentru a opera pe 16 biți.
  • PUSHFD: Conținutul RFLAGS (32 biți) este împins pe stivă (operație de citire) - în modul 64 biți, instrucțiunea se comportă ca PUSHFQ.
  • PUSHFQ: Conținutul RFLAGS (64 de biți) este împins pe stivă (operație de citire).

Exemplu de utilizare a RFLAGS

NB: Aceste coduri diferite pot fi executate numai pe un procesor din familia x86-64 (64 biți).

Limbi C sau C ++

  • Microsoft Visual C ++
#include <iostream> int main(void) { unsigned long long var_RFLAGS = 0; __asm{ PUSHFQ; // pousse les 64 bits de RFLAGS sur la pile POP var_RFLAGS; // met RFLAGS dans la variable var_RFLAGS } std::cout << std::hex << "Valeur du registre RFLAGS : 0x" << var_RFLAGS; return 0; }

Vezi și tu

Conexiuni

EFLAGS: http://www.lifl.fr/~sedoglav/Archi/TP022.html