Récupération des flags du processeur

Résolu
Oeil_de_taupe Messages postés 150 Date d'inscription samedi 31 janvier 2004 Statut Membre Dernière intervention 16 février 2009 - 18 sept. 2006 à 21:02
Oeil_de_taupe Messages postés 150 Date d'inscription samedi 31 janvier 2004 Statut Membre Dernière intervention 16 février 2009 - 19 sept. 2006 à 22:09
Bonjour,

J'ai essayé, après avoir lu beaucoup de théorie sur l'assembleur sur X86, de faire un programme qui utilise les flags d'information du processeur. Ce que j'ai voulu testé est le flag OF (overflow). J'ai donc fais un petit programme qui fait un overflow avec ce code :

mov al, 0xFF
add al, 0x01

Puis j'ai récupéré les flags du processeurs (c'est la seule façon que j'ai trouvée) et j'ai isolé le 12 ème bit (celui de OF).

pushf
pop bx

%define pow2(a) 1 << a
%define OF 11
and bx, pow2(OF)

Le contenu de BX devrait donc donné l'état de OF (si OF=1, BX>0 et si OF=1 BX>0) mais la valeur de BX égale constamment 0.
Je ne sais pas si qqun aurait un exemple de code qui isole un flag en particulier afin que je puisse chercher le problème dans mon code.

Merci d'avance.

PS: J'ai testé avec des flags comme CF et avec eux ça marche!

4 réponses

cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
19 sept. 2006 à 08:22
Bonjour Oeil_de_taupe,


Sauf erreur de ma part, je crois que tu confonds l'overflow et la retenue.


La retenue apparait lorsqu'un registre présente une valeur plus faible (en apparence) après une addition d'un nombre positif. Dans ton cas on a:


0xFF + 0x01 retenue (C) + 0x00  0x100 + 0x00

L'overflow apparait lorsque l'addition de deux nombres positifs donne un nombre négatif. Par exemple:
0x7F (+127) + 0x01 = 0x80 (-128).


Rappel: en binaire signé on a:


positif si compris entre 0x00 et 0x7F (0 à +127)


négatif si compris entre 0x80 et 0xFF (-128 à -1)

A+
3
Oeil_de_taupe Messages postés 150 Date d'inscription samedi 31 janvier 2004 Statut Membre Dernière intervention 16 février 2009
19 sept. 2006 à 00:43
Je viens de constater que mon livre sur l'assembleur est légèrement incomplet puisqu'il omet de présenter les instructions jc/jnc/jo/jno etc...

J'ai donc testé avec ces instructions plutôt que d'extraire le registre de flags directement, et magie! L'instruction jo (qui saute si il y a un dépassement de capacité) ne saute pas lorsque j'en crée artificiellement un dans le programme! Par contre jc/jnc fonctionnent.

Ceci fait que, finallement, ma technique pour accéder aux flags marchait. C'est tous simplement les instructions :  "mov al, 0xFF" puis "add al, 0x01" qui ne font pas de overflow.
Une autre possibilité est que le flag de dépassement de capacité n'est pas activé en 16 bit (je fais des fichiers COM), mais j'ai beau fouiller le web je trouve personne qui affirme ceci...
0
Oeil_de_taupe Messages postés 150 Date d'inscription samedi 31 janvier 2004 Statut Membre Dernière intervention 16 février 2009
19 sept. 2006 à 21:28
Merci beaucoup Nasman !

Grâce à toi j'ai enfin compris la différence entre le carry flag (flag de retenue) et l'overflow. Et si je ne me trompe pas l'arithmétique signée n'a pas d'instruction spéciale, ce sont les instructions add et sub qui font l'affaire (pour la division et la multiplication il y a idiv et imul).

Je profite juste du faite que ton pseudo soit NASMAN pour te poser une question sur l'opérande de concaténation dans NASM : "%+". Chez moi NASM m'affiche une erreur lorsque je veux l'utiliser.
Par exemple avec un code comme ceci (donné en exemple dans le manuel de NASM) :

%define BDASTART 400h ; Start of BIOS data area

struc tBIOSDA ; its structure
.COM1addr RESW 1
.COM2addr RESW 1
; ..and so on
endstruc

%define BDA(x) BDASTART + tBIOSDA. %+ x

puis pour utiliser le macro:
mov ax,BDA(COM1addr)

mais chez moi NASM lève une erreur de ce type:

main.asm:16: symbol `tBIOSDA.' undefined
0
Oeil_de_taupe Messages postés 150 Date d'inscription samedi 31 janvier 2004 Statut Membre Dernière intervention 16 février 2009
19 sept. 2006 à 22:09
Je tiens à le signaler. L'erreur précédente vient du faite que j'utilisais une vieille version de NASM !

En pernant la dernière version sur le site je peux maintenant utiliser cette fonctionalité sans problème.


Et merci encore à Nasman pour m'avoir dépanné.
0