Assemblage x86: instructions INC et DEC et indicateur de débordement
En x86 assemblée, le débordement de l'indicateur est défini lorsqu'un add
ou sub
opération sur un entier signé de débordements, et le porte drapeau est défini lors d'une opération sur un nombre entier non signé de débordement.
Cependant, quand il s'agit de la inc
et dec
instructions, la situation semble s'être quelque peu différente. Selon cette site weble inc
instruction n'a pas d'incidence sur le drapeau de portage à tous.
Mais je ne trouve aucune information sur la façon inc
et dec
incidence sur l'indicateur de débordement, si à tous.
Ne inc
ou dec
définir l'indicateur de débordement lors d'un dépassement d'entier se produit? Et est ce comportement identique pour les entiers signés et non signés?
============================= MODIFIER =============================
Ok, donc, essentiellement, le consensus est que l'INC et DEC devrait se comporter de la même AJOUTER de la et SOUS, en termes de définition des drapeaux, à l'exception de la retenue. C'est aussi ce qu'il dit dans l'Intel manuelle.
Le problème est que je ne peut pas reproduire ce comportement dans la pratique, quand il s'agit des entiers non signés.
Envisager l'assemblage suivant le code (en utilisant GCC assembly en ligne pour le rendre plus facile d'imprimer les résultats.)
int8_t ovf = 0;
__asm__
(
"movb $-128, %%bh;"
"decb %%bh;"
"seto %b0;"
: "=g"(ovf)
:
: "%bh"
);
printf("Overflow flag: %d\n", ovf);
Ici, nous décrémentation signé de 8 bits de la valeur de -128. Depuis -128 est la plus petite valeur possible, un débordement est inévitable. Comme prévu, cette affiche: Overflow flag: 1
Mais lorsque nous faisons la même chose avec un unsigned valeur, le comportement n'est pas que j'attends:
int8_t ovf = 0;
__asm__
(
"movb $255, %%bh;"
"incb %%bh;"
"seto %b0;"
: "=g"(ovf)
:
: "%bh"
);
printf("Overflow flag: %d\n", ovf);
Ici, je incrémenter un entier non signé de 8 bits valeur de 255. Depuis 255 est la plus grande valeur possible, un débordement est inévitable. Cependant, cette affiche: Overflow flag: 0
.
Hein? Pourquoi n'a t il pas de définir l'indicateur de débordement dans ce cas?
source d'informationauteur Channel72
Vous devez vous connecter pour publier un commentaire.
L'indicateur de débordement est défini lors de l'opération serait de provoquer un changement de signe. Votre code est très proche. J'ai été en mesure de mettre le drapeau avec la suivante (VC++) code:
Quand BH est incrémenté l'ESM changements de 0 à 1, causant la DE à être ensemble.
Cela définit également la DE:
Gardez à l'esprit que le processeur ne fait pas de distinction entre les entiers signés et non signés numéros. Lorsque vous utilisez le complément de 2 arithmétique, vous pouvez avoir un ensemble d'instructions qui gèrent à la fois. Si vous voulez tester non signés, de dépassement, vous devez utiliser le porte drapeau. Depuis INC/DEC n'affectent pas le drapeau de portage, vous devez utiliser ADD/SUB pour ce cas.
Intel® 64 et IA-32 Architectures Développeur de Logiciels les Manuels d'
Regarder le manuel approprié L'Instruction De Référence, A-M. Chaque instruction est précisément documenté.
Ici est l'INC article sur les drapeaux:
essayez de changer votre test à passer dans le nombre, plutôt que de coder en dur, puis une boucle qui tente le tout pour 256 nombres pour trouver celui si n'importe qui affecte le drapeau. Ou ont l'asm effectuer la boucle et de sortie quand il frappe le drapeau et ou quand il s'enroule autour du nombre, il a commencé avec (commencer avec quelque chose d'autre que 0x00, 0x7f, 0x80, ou 0xFF).
MODIFIER
Inc débordements quand il va partir 0x7F à 0x80. dec débordements quand il va partir 0x80 à 0x7F, je soupçonne que le problème est dans la façon dont vous utilisez assembleur en ligne.
Que de nombreuses autres réponses ont souligné,
INC
etDEC
n'affectent pas laCF
alors queADD
etSUB
faire.Ce qui n'a pas été dit encore, cependant, est que cela pourrait faire une différence de performance. Pas que vous devez généralement être dérangé par sauf si vous essayez d'optimiser l'enfer hors de la routine, mais essentiellement de ne pas le réglage de la
CF
signifie queINC
/DEC
écrire à seulement une partie de l'historique des indicateurs, ce qui peut provoquer une de drapeaux partiels registre de décrochagevoir Intel ® 64 et IA-32 Optimisation des Architectures Manuel ou Agner Brouillard d'optimisation de manuels.http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-2.html#HEADING2-117
Ce que le processeur n'est de définir les indicateurs pour les résultats de ces instructions (ajouter, adc, dec, inc, les cff, les sous) pour les entiers signés et non signés cas, j'ai e de deux différents drapeau résultats pour chaque op. L'alternative serait d'avoir deux jeux d'instructions où l'on définit signé liées drapeaux et les autres non signés. Si l'émission est un compilateur à l'aide de variables unsigned à l'opération, il permettra de tester de transporter et de zéro (jc, jnc, jb, jbe, etc), s'il est signé par les tests de débordement, de signer et de zéro (jo, jno, jg, jng, jl, jle etc).
Le CPU/ALU est seulement capable de gérer non signé binaire des nombres, et ensuite, il utilise DE, FC, AF, SF, ZF, etc., pour vous permettre de décider de l'utiliser comme un signé nombre (DE), un nombre non signé (CF) ou un numéro de BCD (AF).
Au sujet de votre problème, n'oubliez pas de considérer les nombres binaires eux-mêmes, non signée.
en outre, le débordement et le besoin DE 3 numéros: Le numéro d'entrée, un deuxième numéro à utiliser dans le calcul, et le nombre de résultat.
Débordement est activée uniquement si les premier et deuxième nombres ont la même valeur pour le bit de signe (le bit le plus significatif) et le résultat est un signe différent. Comme, l'ajout de 2 nombres négatifs a entraîné un nombre positif, ou l'ajout de 2 nombres positifs a entraîné un nombre négatif:
Pour votre premier problème, vous utilisez
-128
que le premier numéro. Le deuxième nombre est implicitement-1
utilisé par le DEC instruction. Donc, nous avons vraiment les nombres binaires0x80
et0xFF
. Les deux ont le bit de signe défini à 1. Le résultat est0x7F
qui est un nombre avec le bit de signe à 0. Nous avons eu 2 premiers nombres avec le même signe, et un résultat avec un signe différent, donc nous indiquer un dépassement de capacité.-128-1
entraîné127
et donc l'indicateur de débordement est défini pour indiquer un mauvais signé résultat.Pour ton deuxième problème, vous utilisez
255
que le premier numéro. Le deuxième nombre est implicitement1
utilisé par l'INC instruction. Donc, nous avons vraiment les nombres binaires0xFF
et0x01
. Les deux ont un autre bit de signe, de sorte qu'il n'est pas possible d'obtenir un dépassement de capacité (il est seulement possible de débordement lorsque fondamentalement, l'ajout de 2 nombres de même signe, mais il n'est jamais possible à débordement avec 2 numéros de un signe différent parce qu'ils ne mènera jamais à aller au-delà de la possible valeur signée). Le résultat est0x00
et il ne définit pas l'indicateur de débordement car255+1
ou plus exactement,-1+1
donne 0, ce qui est évidemment correct pour la signature de l'arithmétique.Rappelez-vous que pour l'indicateur de débordement à régler, les 2 numéros ajoute/soustrait besoin d'avoir le bit de signe avec la même valeur, et alors le résultat doit avoir un bit de signe avec une valeur différente de la leur.