Langage assembleur - Instructions logiques

Les instructions logiques sont utilisées pour des opérations au niveau du bit en programmation assembleur, largement utilisées pour le masquage, l'extraction de bits, le positionnement de drapeaux et la multiplication/division efficace.


AND - AND bit à bit

ANDEffectue une opération AND bit à bit sur deux opérandes (le résultat est 1 uniquement lorsque les deux bits valent 1).

Exemple

; Chemin du fichier : and_demo.asm
; Exemple d'instruction AND

section .text
    global _start

_start:
    ; AND bit à bit de base
    mov eax, 0x0F0F             ; 0000 1111 0000 1111
    and eax, 0x00FF             ; 0000 0000 1111 1111
    ; Résultat : eax = 0x000F ; 0000 0000 0000 1111

    ; Technique courante 1 : masquer les 4 bits de poids faible (conserver les 4 bits de poids faible)
    mov eax, 0xAB               ; 1010 1011
    and eax, 0x0F               ; 0000 1111
    ; eax = 0x0B ; 0000 1011

    ; Technique courante 2 : vérifier la parité (AND avec 1)
    mov eax, 42                 ; Pair
    and eax, 1                  ; eax = 0 (pair)
    ; La représentation binaire de 42 se termine par 0, 42 & 1 = 0

    mov eax, 43                 ; Impair
    and eax, 1                  ; eax = 1 (impair)
    ; La représentation binaire de 43 se termine par 1, 43 & 1 = 1

    ; Technique courante 3 : mettre à zéro un registre
    xor eax, eax                ; Équivalent à mov eax, 0, mais plus rapide et plus court

    ; AND positionne les drapeaux : CF=0, OF=0, ZF et SF dépendent du résultat
    mov eax, 1
    mov ebx, 0
    int 0x80

OR - OU bit à bit

OREffectue une opération OU bit à bit sur deux opérandes (le résultat est 1 si au moins un bit est 1).

Exemple

; Exemple d'instruction OR

    ; Fusionner les bits de drapeau
    mov eax, 0x0F00             ; 0000 1111 0000 0000
    or  eax, 0x00FF             ; 0000 0000 1111 1111
    ; eax = 0x0FFF ; 0000 1111 1111 1111

    ; Définir un bit spécifique (mettre le bit 3 à 1)
    mov eax, 0                  ; 0000 0000
    or  eax, 0x08               ; 0000 1000
    ; eax = 0x8 ; 0000 1000

    ; Conversion de casse : majuscules en minuscules
    mov al, 'A'                 ; al = 0x41 (0100 0001)
    or  al, 0x20                ; 0x20 = 0010 0000
    ; al = 0x61 = 'a' ; 0110 0001

NOT - NOT bit a bit

NOTInverte ogni bit dell'operando (0 diventa 1, 1 diventa 0).

Exemple

; esempio di istruzione NOT

    mov eax, 0x0F0F0F0F        ; 0000 1111 0000 1111 ...
    not eax                     ; 1111 0000 1111 0000 ...
    ; eax = 0xF0F0F0F0

    ; NOT non influisce su alcun flag (a differenza di AND/OR/XOR)

XOR - XOR bit a bit

XOREsegue un'operazione XOR bit a bit su due operandi (il risultato è 1 se i bit differiscono, 0 se sono uguali).

Exemple

; Percorso file: xor_demo.asm
; esempio di istruzione XOR

section .text
    global _start

_start:
    ; XOR di base
    mov eax, 0x0F0F             ; 0000 1111 0000 1111
    xor eax, 0x00FF             ; 0000 0000 1111 1111
    ; Résultat : eax = 0x0FF0 ; 0000 1111 1111 0000

    ; Technique classique 1 : mettre un registre à zéro (plus efficace que mov reg, 0)
    xor eax, eax                ; eax = 0, n'occupe que 2 octets
    xor ebx, ebx
    xor ecx, ecx

    ; Technique classique 2 : échanger deux registres (aucun troisième registre temporaire nécessaire)
    mov eax, 100                ; eax = 100
    mov ebx, 200                ; ebx = 200
    xor eax, ebx                ; eax = 100 xor 200
    xor ebx, eax                ; ebx = 200 xor (100 xor 200) = 100
    xor eax, ebx                ; eax = (100 xor 200) xor 100 = 200
    ; Maintenant eax = 200, ebx = 100 (échange terminé !)

    ; Technique classique 3 : chiffrement/déchiffrement simple
    mov al, 'A'                 ; Caractère original 'A' = 0x41
    xor al, 0x55                ; Chiffrement : al = 'A' xor 0x55
    ; al est maintenant une valeur brouillée
    xor al, 0x55                ; Déchiffrement : XOR avec 0x55 à nouveau pour restaurer
    ; al = 'A' est de retour !

    mov eax, 1
    mov ebx, 0
    int 0x80

L'astuce d'échange par XOR est sympa, mais sur les processeurs modernes, elle est moins efficace que d'utiliserXCHGune instruction ou un registre temporaire. C'est bon à savoir, mais pas besoin d'insister pour l'utiliser.


Instructions de décalage

Les instructions de décalage déplacent les bits binaires vers la gauche ou la droite, couramment utilisées pour une multiplication et une division efficaces (multiplier par 2, diviser par 2, etc.).

InstructionFonctionExemple
SHLDécalage logique à gauche (les bits sortent à gauche, des zéros remplissent à droite)shl eax, 1(multiplier par 2)
SHRDécalage logique à droite (les bits sortent à droite, des zéros sont insérés à gauche)shr eax, 1(division non signée par 2)
SALDécalage arithmétique à gauche (identique à SHL)sal eax, 1
SARDécalage arithmétique à droite (les bits sortent à droite, le bit de signe est conservé à gauche)sar eax, 1(division signée par 2)

Exemple

; Chemin du fichier : shift_demo.asm
; Exemple d'instruction de décalage

section .text
    global _start

_start:
    ; SHL : décalage logique à gauche = multiplication par une puissance de 2
    mov eax, 10                 ; eax = 10 (1010)
    shl eax, 1                  ; eax = 20 (10100), soit 10×2
    shl eax, 2                  ; eax = 80 (1010000), soit 20×4

    ; SHR : décalage logique à droite = division non signée par une puissance de 2
    mov eax, 80                 ; eax = 80
    shr eax, 3                  ; eax = 10, soit 80÷8

    ; SAR : décalage arithmétique à droite = division signée par une puissance de 2 (préserve le bit de signe)
    mov eax, -16                ; eax = -16 (0xFFFFFFF0)
    sar eax, 2                  ; eax = -4 (0xFFFFFFFC), soit -16÷4
    ; SAR vs SHR :
    ; Si eax = 0xFFFFFFF0 (-16), SHR donne 0x3FFFFFFC (un très grand nombre positif)
    ; alors que SAR donne 0xFFFFFFFC (-4), en préservant le bit de signe

    ; Le dernier bit décalé vers l'extérieur est placé dans le drapeau CF
    mov eax, 5                  ; 0101
    shr eax, 1                  ; eax = 2, CF = 1 (le 1 final a été décalé vers l'extérieur)
    jc carry_was_set            ; Si CF=1, le nombre d'origine était impair

carry_was_set:
    mov eax, 1
    mov ebx, 0
    int 0x80

Instructions de rotation

Les décalages de rotation réinjectent le bit décalé à l'autre extrémité, formant une rotation :

InstructionDescription
ROLRotation à gauche (contourne CF)
RORRotation à droite (contourne CF)
RCLRotation à gauche via la retenue (implique CF)
RCRRotation à droite via la retenue (implique CF)

Exemple

; Exemple de décalage rotatif

    ; ROL : rotation à gauche
    mov al, 0x85                ; 1000 0101
    rol al, 1                   ; Décalage à gauche de 1 bit : 0000 1011
    ; CF = 1 (le bit de poids fort est décalé vers CF)
    ; En même temps, le 1 d'origine dans CF est décalé vers le bit de poids faible, formant une rotation

    ; Effet réel de ROL : décalage à gauche de 1 bit, le bit de poids fort va à la fois dans CF et dans le bit de poids faible
    ; 1000 0101 -> ROL 1 -> 0000 1011

    ; RCL : rotation à gauche via la retenue (CF participe à la rotation)
    clc                         ; Mettre CF à 0
    mov al, 0x85                ; 1000 0101
    rcl al, 1                   ; CF participe : CF bit7...bit0 -> CF
    ; Résultat : 0000 1010, CF = 1

    ; Les décalages circulaires sont couramment utilisés dans les algorithmes de chiffrement et la manipulation de bits

Utilisations pratiques des opérations logiques

Un exemple complet — implémentation d'un système simple de drapeaux binaires à l'aide d'opérations logiques :

Exemple

; Chemin de fichier : bit_flags.asm
; Implémentation d'un système de drapeaux binaires à l'aide d'opérations logiques

section .data
    flags db 0                  ; 8 bits de drapeau, initialement tous à 0
    ; bit0 : actif ou non
    ; bit1 : visible ou non
    ; bit2 : doit être sauvegardé ou non
    ; bit3 : modifié ou non

    FLAG_ACTIVE equ 1           ; 0000 0001
    FLAG_VISIBLE equ 2          ; 0000 0010
    FLAG_NEED_SAVE equ 4        ; 0000 0100
    FLAG_MODIFIED equ 8         ; 0000 1000

section .text
    global _start

_start:
    ; Définition des bits de drapeau : OR
    mov al, [flags]
    or  al, FLAG_ACTIVE         ; Mettre à 1 le bit0
    or  al, FLAG_VISIBLE        ; Mettre à 1 le bit1
    ; al = 0000 0011 = 3
    mov [flags], al

    ; Vérification des bits de drapeau : AND + TEST
    test byte [flags], FLAG_ACTIVE    ; Tester si le bit0 est à 1
    jnz is_active                     ; ZF=0 signifie que le bit est 1

is_active:
    ; Effacement des bits de drapeau : AND + NOT
    mov al, [flags]
    and al, ~FLAG_VISIBLE       ; Effacer le bit1 (conserver les autres bits inchangés)
    ; al = 0000 0001 = 1
    mov [flags], al

    ; Basculement des bits de drapeau : XOR
    mov al, [flags]
    xor al, FLAG_MODIFIED       ; Inverser le bit3
    ; S'il était 0, il devient 1, s'il était 1, il devient 0

    mov eax, 1
    mov ebx, 0
    int 0x80

La manipulation de bits de drapeau est extrêmement courante en programmation système. Les noyaux de systèmes d'exploitation, les pilotes de périphériques et les systèmes embarqués utilisent largement cette technique pour gérer l'état.

Autres extensions