Recherche…


Sauts inconditionnels

jmp a_label                      ;Jump to a_label
jmp bx                           ;Jump to address in BX
jmp WORD [aPointer]              ;Jump to address in aPointer
jmp 7c0h:0000h                   ;Jump to segment 7c0h and offset 0000h
jmp FAR WORD [aFarPointer]       ;Jump to segment:offset in aFarPointer

Relatif près des sauts

jmp a_label est:

  • près
    Il spécifie uniquement la partie offset de l' adresse logique de destination. Le segment est supposé être CS .
  • relatif
    La sémantique de l' instruction est saut rel octets avant 1 de la prochaine adresse d'instruction ou IP = IP + rel .

L'instruction est codée sous la forme EB <rel8> ou EB <rel16/32> , l'assembleur prenant la forme la plus appropriée, préférant généralement une forme plus courte.
La jmp SHORT a_label par assembleur est possible, par exemple avec NASM jmp SHORT a_label , jmp WORD a_label et jmp DWORD a_label génèrent les trois formes possibles.

Sauts indirects absolus

jmp bx et jmp WORD [aPointer] sont:

  • près
    Ils spécifient uniquement la partie offset de l'adresse logique de destination. Le segment est supposé être CS .
  • indirect indirect
    La sémantique des instructions est sautée à l’adresse dans reg ou mem ou IP = reg , IP = mem .

L'instruction est codée comme FF /4 , pour la mémoire indirecte, la taille de l'opérande est déterminée comme pour tout autre accès mémoire.

Sauts absolus

jmp 7c0h:0000h est:

  • loin
    Il spécifie les deux parties de l'adresse logique : le segment et le décalage.

  • absolute La sémantique de l'instruction passe directement au segment d' adresse : offset ou CS = segment, IP = offset .

L'instruction est codée comme EA <imm32/48> fonction de la taille du code.
Il est possible de choisir entre les deux formes dans un assembleur, par exemple avec NASM jmp 7c0h: WORD 0000h et jmp 7c0h: DWORD 0000h génère la première et la seconde forme.

Sauts absolus indirects

jmp FAR WORD [aFarPointer] est:

  • far Indique les deux parties de l'adresse logique : le segment et le décalage.

  • Absolue indirecte La sémantique de l'instruction est sautée vers le segment: offset stocké dans mem 2 ou CS = mem[23:16/32], IP = [15/31:0] .

L'instruction est codée comme FF /5 , la taille de l'opérande peut être contrôleur avec les spécificateurs de taille.
Dans NASM, un peu non intuitif, ils sont jmp FAR WORD [aFarPointer] pour un opérande 16:16 et jmp FAR DWORD [aFarPointer] pour un opérande 16:32 .


Sauts manquants

  • presque absolu
    Peut être émulé avec un saut presque indirect.

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • loin relatif
    Cela n'a aucun sens ou est trop étroit d'utilisation.


1 Deux complément permet de spécifier un décalage signé et donc de revenir en arrière.
2 Ce qui peut être un seg16: off16 ou un seg16: off32 , de tailles 16:16 et 16:32 .

Conditions de test

Pour utiliser un saut conditionnel, une condition doit être testée. Tester une condition ici ne concerne que l'acte de vérifier les drapeaux, le saut réel est décrit sous sauts conditionnels .

x86 teste les conditions en s'appuyant sur le registre EFLAGS, qui contient un ensemble d'indicateurs que chaque instruction peut potentiellement définir.

Les instructions arithmétiques, comme sub ou add , et les instructions logiques, comme xor ou and , "définissent évidemment les drapeaux". Cela signifie que les drapeaux CF , OF , SF , ZF , AF , PF sont modifiés par ces instructions. Toute instruction est autorisée à modifier les indicateurs, par exemple cmpxchg modifie le ZF .

Toujours vérifier la référence de l'instruction pour savoir quels drapeaux sont modifiés par une instruction spécifique.

x86 possède un ensemble de sauts conditionnels , mentionnés précédemment, qui sautent si et seulement si certains indicateurs sont définis ou si certains sont clairs ou les deux.


Les drapeaux

Les opérations arithmétiques et logiques sont très utiles pour définir les indicateurs. Par exemple, après un sub eax, ebx , pour maintenant détenir des valeurs non signées , nous avons:

Drapeau Quand réglé Lorsque clair
ZF Lorsque le résultat est zéro.
EAX - EBX = 0 ⇒ EAX = EBX
Lorsque le résultat n'est pas nul.
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
CF Quand le résultat a dû être porté pour le MSb.
EAX - EBX <0 ⇒ EAX <EBX
Lorsque le résultat n'a pas besoin d'être porté pour le MSb.
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
SF Lorsque le résultat MSb est défini. Lorsque le résultat MSb n'est pas défini.
DE Quand un débordement signé s'est produit. Lorsqu'un dépassement signé n'a pas eu lieu.
PF Lorsque le nombre de bits défini dans l'octet de résultat le moins significatif est pair. Lorsque le nombre de bits défini dans l'octet de résultat le moins significatif est impair.
UN F Lorsque le chiffre inférieur BCD a généré un report.
C'est le bit 4 transport.
Lorsque le chiffre inférieur BCD n'a pas généré de report.
C'est le bit 4 transport.

Tests non destructifs

Le sub -programme and instructions modifient leur opérande de destination et nécessitent deux copies supplémentaires (sauvegarde et restauration) pour que la destination ne soit pas modifiée.

Pour effectuer un test non destructif, il y a les instructions cmp et test . Ils sont identiques à leur homologue destructeur, sauf que le résultat de l'opération est ignoré et que seuls les indicateurs sont enregistrés .

Destructeur Non destructif
sub cmp
and test

test eax, eax             ;and eax, eax
                          ;ZF = 1 iff EAX is zero

test eax, 03h             ;and eax, 03h
                          ;ZF = 1 if both bit[1:0] are clear
                          ;ZF = 0 if at least one of bit[1:0] is set

cmp eax, 241d             ;sub eax, 241d
                          ;ZF = 1 iff EAX is 241
                          ;CF = 1 iff EAX < 241

Tests signés et non signés

Le processeur ne donne aucune signification particulière pour enregistrer les valeurs 1 , le signe est une construction de programmeur. Il n'y a pas de différence lors du test des valeurs signées et non signées. Le processeur calcule suffisamment de drapeaux pour tester les relations arithmétiques habituelles (égales, inférieures à, supérieures à, etc.) si les opérandes devaient être considérées comme signées et non signées.


1 Bien que certaines instructions ne soient utiles que pour des formats spécifiques, comme le complément à deux. Cela permet de rendre le code plus efficace car l'implémentation de l'algorithme dans le logiciel nécessiterait beaucoup de code.

Sauts conditionnels

En fonction de l'état des indicateurs, le processeur peut soit exécuter soit ignorer un saut. Une instruction qui effectue un saut basé sur les indicateurs tombe sous le nom générique de Jcc - Jump on Condition Code 1 .

Synonymes et terminologie

Afin d'améliorer la lisibilité du code d'assemblage, Intel a défini plusieurs synonymes pour le même code de condition. Par exemple, jae , jnb et jnc ont tous le même code de condition CF = 0 .

Bien que le nom de l'instruction puisse donner une idée très précise de son utilisation, la seule approche utile consiste à reconnaître les indicateurs à tester, puis à choisir les instructions appropriées.
Intel a cependant donné les noms d'instructions qui ont un sens parfait lorsqu'elles sont utilisées après une instruction cmp . Pour les besoins de cette discussion, cmp sera supposé avoir défini les drapeaux avant un saut conditionnel.

Égalité

L'opérande est égal si ZF a été défini, ils diffèrent autrement. Pour tester l'égalité, nous avons besoin de ZF = 1 .

je a_label           ;Jump if operands are equal
jz a_label           ;Jump if zero (Synonym)

jne a_label          ;Jump if operands are NOT equal
jnz a_label          ;Jump if not zero (Synonym)
Instruction Les drapeaux
je , jz ZF = 1
jne , jnz ZF = 0

Plus grand que

Pour les opérandes non signés , la destination est supérieure à la source si le transport n'est pas nécessaire, c'est-à-dire si CF = 0 . Lorsque CF = 0 il est possible que les opérandes soient égaux, le test de ZF va désambiguïser.

jae a_label      ;Jump if above or equal (>=)
jnc a_label      ;Jump if not carry (Synonym)
jnb a_label      ;Jump if not below (Synonym)

ja a_label       ;Jump if above  (>)
jnbe a_label     ;Jump if not below and not equal (Synonym)
Instruction Les drapeaux
jae , jnc , jnb CF = 0
ja , jnbe CF = 0, ZF = 0

Pour les opérandes signés, nous devons vérifier que SF = 0 , sauf en cas de dépassement signé, auquel cas le SF résultant est inversé. Puisque OF = 0 si aucun débordement signé ne s'est produit et 1 sinon, nous devons vérifier que SF = OF .

ZF peut être utilisé pour implémenter un test strict / non strict.

jge a_label      ;Jump if greater or equal (>=)
jnl a_label      ;Jump if not less (Synonym)

jg a_label       ;Jump if greater (>)
jnle a_label     ;Jump if not less and not equal (Synonym)
Instruction Les drapeaux
jge , jnl SF = OF
jg , jnle SF = OF, ZF = 0

Moins que

Ceux-ci utilisent les conditions inversées ci-dessus.

jbe a_label      ;Jump if below or equal (<=)
jna a_label      ;Jump if not above (Synonym)

jb a_label       ;Jump if below (<)
jc a_label       ;Jump if carry (Synonym)
jnae a_label     ;Jump if not above and not equal (Synonym)

;SIGNED 

jle a_label      ;Jump if less or equal (<=)
jng a_label      ;Jump if not greater (Synonym)

jl a_label       ;Jump if less (<)
jnge a_label     ;Jump if not greater and not equal (Synonym)
Instruction Les drapeaux
jbe , jna CF = 1 ou ZF = 1
jb , jc , jnae CF = 1
jle , jng SF! = OF ou ZF = 1
jl , jnge SF! = De

Drapeaux spécifiques

Chaque indicateur peut être testé individuellement avec j<flag_name>flag_name ne contient pas le F final (par exemple, CFC , PFP ).

Les autres codes non couverts sont les suivants:

Instruction Drapeau
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jp , jpe (e = pair) PF = 1
jnp , jpo (o = impair) PF = 0

Un saut conditionnel supplémentaire (extra)

Un saut conditionnel x86 spécial ne teste pas le drapeau. Au lieu de cela, il teste la valeur du registre cx ou ecx (sur la base du mode d'adresse actuel du processeur, soit 16 ou 32 bits), et le saut est exécuté lorsque le registre contient zéro.

Cette instruction a été conçue pour la validation du registre de compteur ( cx/ecx ) avant les instructions de type rep , ou avant les loop de loop .

jcxz  a_label   ; jump if cx (16b mode) or ecx (32b mode) is zero
jecxz a_label   ; synonym of jcxz (recommended in source code for 32b target)
Instruction Registre (pas de drapeau)
jcxz , jecxz cx = 0 (mode 16b)
jcxz , jecxz ecx = 0 (mode 32b)

1 Ou quelque chose comme ça.

Tester les relations arithmétiques

Entiers non signés

Plus grand que

cmp eax, ebx
ja a_label  

Meilleur que ou égal

cmp eax, ebx
jae a_label  

Moins que

cmp eax, ebx
jb a_label  

Inférieur ou égal

cmp eax, ebx
jbe a_label 

Égal

cmp eax, ebx
je a_label 

Inégal

cmp eax, ebx
jne a_label     

Entiers signés

Plus grand que

cmp eax, ebx
jg a_label  

Meilleur que ou égal

cmp eax, ebx
jge a_label  

Moins que

cmp eax, ebx
jl a_label  

Inférieur ou égal

cmp eax, ebx
jle a_label 

Égal

cmp eax, ebx
je a_label 

Inégal

cmp eax, ebx
jne a_label 

a_label

Dans les exemples ci-dessus, le a_label est la destination cible du processeur lorsque la condition testée est "true". Lorsque la condition testée est "false", le processeur continue sur l'instruction suivante après le saut conditionnel.

Des synonymes

Il existe des synonymes d'instructions qui peuvent être utilisés pour améliorer la lisibilité du code.
Par exemple ja et jnbe (Jump non inférieur ni égal) sont la même instruction.

Codes compagnons non signés signés

Opération Non signé Signé
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
≠,! =, <> jne jne


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow