L'indicateur CF
est défini lorsque nous comparons deux chiffres et un nombre est inférieur à un autre:
mov eax,1
cmp eax,2
jb truWay
Sous forme binaire:
1=00000001
2=00000010=11111101+1(add. code)=11111110и
00000001+11111110=11111111(no carry)
Pourquoi l'instruction cmp eax,2
définit-elle l'indicateur CF
? Il n'y a pas eu de report, ou je me trompe.
2 réponses
Il y a effectivement emprunter . CF
est défini par l'instruction cmp
s'il y a emprunter .
Votre instruction cmp
effectue la soustraction suivante:
1 = 0001
- 2 = 0010
--------------
1111
Pour la première colonne la plus à droite, il n'y a rien de spécial: 1 - 0 = 1
.
Pour la deuxième colonne la plus à droite, il y a un emprunter (c'est-à-dire: un 1
est "emprunté" à l'une des colonnes suivantes). L'emprunt est nécessaire car 0 < 1
. Le résultat de cette colonne est alors 10 - 1 = 1
.
Notez cependant que pour le premier opérande il n'y a pas une seule colonne à gauche avec un 1
à emprunter, donc un emprunter se produit: un emprunt sort pour le plus significatif bit, qui définit en fait CF
.
Votre opération de soustraction serait en fait comme définir CF
(c'est-à-dire: "emprunter" ou "obtenir" un 1
pour le MSB du premier opérande) et effectuer la soustraction suivante:
10001
- 0010
-------
1111
Notez que le premier opérande a un 1
sur le côté gauche de son vrai MSB. Ce 1
n'était pas là avant et il représente l ' emprunt .
D'abord:
Le résultat de a-b
est le même que le résultat de a+(-b)
.
Cependant, les indicateurs définis par l'opération a-b
ne sont PAS (du moins pas toujours) les mêmes indicateurs que les indicateurs définis par l'opération a+(-b)
!
Cela peut être vu en comparant différents types de CPU (par exemple, un processeur x86 moderne et le 6502 historique):
Les valeurs des flags après l'opération a+b
sont les mêmes sur le x86 et le 6502 tandis que le "carry flag" a exactement la signification opposée sur les deux CPU après l'opération a-b
.
Cela signifie que le "drapeau de retenue" a la même valeur après l'opération a+(-b)
sur les deux processeurs tandis que la valeur après a-b
diffère toujours sur les deux processeurs.
Deuxième:
Sur le x86, le «drapeau de retenue» est défini comme «emprunter» pour les soustractions. Vous pouvez émuler cela en
- étendre les deux nombres à un nombre avec plus de bits - par exemple 9 au lieu de 8 bits
- puis rendant le nombre "étendu" négatif
- puis faire l'addition
- ignorer le report dans l'ajout
- au lieu d'utiliser le bit le plus élevé du résultat comme report
Exemple:
1 = 00000001 (8 bit) = 0 00000001 (9 bit)
2 = 00000010 (8 bit) = 0 00000010 (9 bit)
3 = 00000011 (8 bit) = 0 00000011 (9 bit)
=> -2 = 1 11111110 (9 bit!)
Do the addition:
3 + (-2) = 1000000001 (9 bit plus carry)
1 + (-2) = 111111111 (9 bit)
Ignore carry:
3 + (-2) = 000000001 (9 bit)
1 + (-2) = 111111111 (9 bit)
Use the highest bit as carry:
3 + (-2) = 000000001 = 0 00000001 = (no carry) 00000001
1 + (-2) = 111111111 = 1 11111111 = (carry) 11111111
De nouvelles questions
assembly
Questions relatives au langage d'assemblage. Veuillez marquer le processeur et / ou le jeu d'instructions que vous utilisez, ainsi que l'assembleur, un jeu valide doit être comme ceci: (assembly, x86, gnu) Notez que vous devez utiliser la balise ".net-assembly" à la place pour Les langages d'assemblage .NET et pour le bytecode Java, utilisez plutôt la balise java-bytecode-asm.