Question

D'après ce que j'ai lu, il semble y avoir 9 drapeaux différents. Est-il possible de les lire / modifier directement? Je sais que je peux par exemple savoir si le drapeau zéro est défini après une instruction cmp / jmp, mais je demande s'il est possible de faire quelque chose comme

mov eax, flags

ou quelque chose.

Aussi, pour l'écriture, est-il possible de les définir à la main?

Était-ce utile?

La solution

Certains indicateurs peuvent être définis ou effacés directement avec des instructions spécifiques:

  • CLC , STC et CMC : effacer, définir et compléter l'indicateur de report
  • CLI et STI : effacer et définir le drapeau d'interruption (ce qui devrait être fait de manière atomique)
  • CLD et STD : efface et définit l'indicateur de direction

Pour lire et écrire le signe, le zéro, le report auxiliaire, la parité et les indicateurs de report, vous pouvez utiliser LAHF pour charger les 8 bits inférieurs (ces 5 indicateurs plus 3 indéterminés) dans le registre AH et vous pouvez utiliser SAHF pour stocker ces valeurs de AH dans le registre d'indicateurs.

Vous pouvez également utiliser l'instruction PUSHF . pour placer les indicateurs sur la pile, les lire et les modifier, puis utiliser le POPF 1 pour les stocker dans le registre des indicateurs.

Notez que vous ne pouvez pas définir les indicateurs VM et RF avec POPF - ils conservent leurs valeurs précédentes. De même, vous ne pouvez modifier le niveau de privilège d'E / S que lorsque vous l'exécutez au niveau de privilège 0 et l'indicateur d'interruption ne peut être modifié que lorsque vous l'exécutez à un niveau de privilège au moins égal à celui du niveau de privilège d'E / S.

Note de bas de page 1:

Notez que popf est assez lent sur les processeurs modernes; consultez le guide d'optimisation d'Agner Fog . Il est microcodé car, en mode noyau, il peut changer de niveau de privilège IO, AC et IO. Nous subissons la pénalité quel que soit le mode des processeurs actuels car les décodeurs ne sont pas sensibles au mode.

Si possible, utilisez lahf / sahf au lieu de pushf / popf pour améliorer les performances, ou enregistrez un seul drapeau qui vous tient à cœur, comme setc al , puis plus tard add al, 255 dans définissez CF = (AL! = 0) . Ou setnc al / sous al, 1 ou autre. Les séquences pour définir ou effacer SF ou OF sur la base d’un registre 0 ou 1 sont également simples, avec / sans inversion du drapeau.

Autres conseils

Vous pouvez utiliser les instructions pushf et popf pour pousser les drapeaux sur la pile, vous pouvez les modifier, puis les supprimer.

Si vous n’avez besoin que de l’octet inférieur du registre de drapeaux (qui contient SF, ZF, AF, PF, CF), l’instruction étrange mais pratique LAHF (ha ha) charge les 8 derniers bits de la les drapeaux s’inscrivent dans AH et son homologue SAHF pour stocker AH dans les drapeaux.

En ce qui concerne plus spécifiquement le drapeau de report, x86 offre les services CLC, STC et CMC pour effacer, définir et compléter le drapeau de report, respectivement.

La méthode la plus simple consiste à utiliser pushf / popf .

Si vous souhaitez déplacer eflags dans eax , utilisez le code ci-dessous.

pushf                  # push eflags into stack
pop %eax               # pop it into %eax

SETcc

Cette famille d'instructions est un autre moyen d'observer certains drapeaux / combinaisons de drapeaux.

Il définit la valeur d'un octet en fonction des drapeaux individuels.

exemple, pour CF :

stc
setc al
; al == 1

clc
setc al
; al == 0

.

  • LAHF: charge les indicateurs d'état dans AH
  • Copie l'octet de poids faible du registre EFLAGS, y compris les drapeaux Sign, Zero et Carry.
  • Enregistrez une copie des drapeaux dans une variable pour la sauvegarde

    .data
     saveflags BYTE ? 
    .code 
     lahf ; load flags into AH 
     mov saveflags,ah ; save them into a variable 
    
  • SAHF: stocke AH dans des indicateurs d'état

  • Copie AH dans l'octet de poids faible du registre EFLAGS
  • Récupérer la valeur des indicateurs stockés précédemment

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