Come leggere e scrivere registri flag x86 direttamente?

Da quello che ho letto, sembra che ci siano 9 bandiere diverse. È ansible leggerli / modificarli direttamente? So che posso sapere per esempio se il flag zero è impostato dopo aver fatto un’istruzione cmp / jmp, ma sto chiedendo se è ansible fare qualcosa come

mov eax, flags 

o qualcosa.

Inoltre, per scrivere, è ansible impostarli a mano?

Alcuni flag possono essere impostati o cancellati direttamente con istruzioni specifiche:

  • CLC , STC e CMC : cancella, imposta e completa il flag di carry
  • CLI e STI : cancella e imposta il flag di interrupt (che dovrebbe essere fatto atomicamente)
  • CLD e STD : cancella e imposta il flag di direzione

Per leggere e scrivere i flag di segno, zero, trasporto ausiliario, parità e trasporto, è ansible utilizzare LAHF per caricare gli 8 bit più bassi (quei 5 flag più 3 bit indeterminati) nel registro AH, e si può usare SAHF per memorizzare quelli i valori da AH indietro nel registro delle bandiere.

È inoltre ansible utilizzare l’istruzione PUSHF per spingere i flag sullo stack, leggerli e modificarli nello stack e quindi utilizzare l’istruzione POPF per memorizzarli nuovamente nel registro flags.

Si noti che non è ansible impostare i flag VM e RF con POPF: mantengono i loro valori precedenti. Allo stesso modo, è ansible modificare il livello di privilegio I / O solo quando si esegue a livello di privilegio 0 e il flag di interruzione può essere modificato solo quando si esegue a un livello di privilegio almeno privilegiato come il livello di privilegio I / O.

Puoi usare le istruzioni pushf e popf che spingono le bandiere in pila, puoi modificarle e poi farle saltare indietro.

Se è necessario solo il byte inferiore del registro flags (che contiene SF, ZF, AF, PF, CF), allora c’è l’istruzione dispari ma conveniente LAHF (ha ha), che carica gli 8 bit inferiori del registro flags in AH, e la sua controparte SAHF per memorizzare AH in bandiere.

Per il flag di carry in particolare, x86 offre CLC, STC e CMC, per cancellare, impostare e completare il flag di carry, rispettivamente.

SETcc

Questa famiglia di istruzioni è un altro modo per osservare alcune bandiere / combinazioni di bandiere. Ad esempio, per CF :

 stc setc al ; al == 1 clc setc al ; al == 0 

JCC

Questa famiglia di istruzioni è ovviamente un’altra possibilità per alcuni flag e potrebbe essere utilizzata per implementare SETcc :

 jc set mov al, 0 jmp end set: mov al, 1 end: 
  • LAHF: carica i flag di stato in AH
  • Copia il byte basso del registro EFLAGS, inclusi i contrassegni Sign, Zero e Carry.
  • Salva una copia delle bandiere in una variabile per sicurezza

     .data saveflags BYTE ? .code lahf ; load flags into AH mov saveflags,ah ; save them into a variable 
  • SAHF: memorizza AH in flag di stato

  • Copia AH nel byte basso del registro EFLAGS
  • Recupera il valore dei flag memorizzati in precedenza

     .code mov ah, saveflags ; load save flags into AH sahf ; copy into flags register