Assembly Language - Logical Instructions

Logical instructions are used for bit-level operations in assembly programming, widely used for masking, bit extraction, flag setting, and efficient multiplication/division.


AND - Bitwise AND

ANDPerforms a bitwise AND operation on two operands (result is 1 only when both bits are 1).

Example

; File path: and_demo.asm
; AND instruction example

section .text
    global _start

_start:
    ; Basic bitwise AND
    mov eax, 0x0F0F             ; 0000 1111 0000 1111
    and eax, 0x00FF             ; 0000 0000 1111 1111
    ; Result: eax = 0x000F ; 0000 0000 0000 1111

    ; Common technique 1: Mask the low 4 bits (keep the low 4 bits)
    mov eax, 0xAB               ; 1010 1011
    and eax, 0x0F               ; 0000 1111
    ; eax = 0x0B                ; 0000 1011

    ; Common technique 2: Check parity (AND with 1)
    mov eax, 42                 ; Even
    and eax, 1                  ; eax = 0 (even)
    ; The binary of 42 ends in 0, 42 & 1 = 0

    mov eax, 43                 ; Odd
    and eax, 1                  ; eax = 1 (odd)
    ; The binary of 43 ends in 1, 43 & 1 = 1

    ; Common technique 3: Clear a register
    xor eax, eax                ; Equivalent to mov eax, 0, but faster and shorter

    ; AND sets flags: CF=0, OF=0, ZF and SF depend on the result
    mov eax, 1
    mov ebx, 0
    int 0x80

OR - Bitwise OR

ORPerforms a bitwise OR operation on two operands (result is 1 if at least one bit is 1).

Example

; OR instruction example

    ; Merge flag bits
    mov eax, 0x0F00             ; 0000 1111 0000 0000
    or  eax, 0x00FF             ; 0000 0000 1111 1111
    ; eax = 0x0FFF              ; 0000 1111 1111 1111

    ; Set a specific bit (set bit 3 to 1)
    mov eax, 0                  ; 0000 0000
    or  eax, 0x08               ; 0000 1000
    ; eax = 0x8                 ; 0000 1000

    ; Case conversion: uppercase to lowercase
    mov al, 'A'                 ; al = 0x41 (0100 0001)
    or  al, 0x20                ; 0x20 = 0010 0000
    ; al = 0x61 = 'a'          ; 0110 0001

NOT - Bitwise NOT

NOTInverts every bit of the operand (0 becomes 1, 1 becomes 0).

Example

; NOT instruction example

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

    ; NOT does not affect any flags (unlike AND/OR/XOR)

XOR - Bitwise XOR

XORPerforms a bitwise XOR operation on two operands (result is 1 if bits differ, 0 if they are the same).

Example

; File path: xor_demo.asm
; XOR instruction example

section .text
    global _start

_start:
    ; Basic XOR
    mov eax, 0x0F0F             ; 0000 1111 0000 1111
    xor eax, 0x00FF             ; 0000 0000 1111 1111
    ; Result: eax = 0x0FF0 ; 0000 1111 1111 0000

    ; Classic technique 1: Clear a register (more efficient than mov reg, 0)
    xor eax, eax                ; eax = 0, only occupies 2 bytes
    xor ebx, ebx
    xor ecx, ecx

    ; Classic technique 2: Swap two registers (no third temporary register needed)
    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
    ; Now eax = 200, ebx = 100 (swap complete!)

    ; Classic technique 3: Simple encryption/decryption
    mov al, 'A'                 ; Original character 'A' = 0x41
    xor al, 0x55                ; Encryption: al = 'A' xor 0x55
    ; al is now some garbled value
    xor al, 0x55                ; Decryption: XOR with 0x55 again to restore
    ; al = 'A' is back!

    mov eax, 1
    mov ebx, 0
    int 0x80

The XOR swap trick is cool, but on modern CPUs it's less efficient than usingXCHGan instruction or a temporary register. It's good to know, but no need to insist on using it.


Shift Instructions

Shift instructions move binary bits to the left or right, commonly used for efficient multiplication and division (multiply by 2, divide by 2, etc.).

InstructionFunctionExample
SHLLogical left shift (bits exit left, zeros fill right)shl eax, 1(multiply by 2)
SHRLogical right shift (bits exit right, zeros fill left)shr eax, 1(unsigned division by 2)
SALArithmetic left shift (same as SHL)sal eax, 1
SARArithmetic right shift (bits exit on the right, sign bit preserved on the left)sar eax, 1(signed division by 2)

Example

; File path: shift_demo.asm
; Shift instruction example

section .text
    global _start

_start:
    ; SHL: logical left shift = multiply by a power of 2
    mov eax, 10                 ; eax = 10 (1010)
    shl eax, 1                  ; eax = 20 (10100), i.e., 10×2
    shl eax, 2                  ; eax = 80 (1010000), i.e., 20×4

    ; SHR: logical right shift = unsigned divide by a power of 2
    mov eax, 80                 ; eax = 80
    shr eax, 3                  ; eax = 10, i.e., 80÷8

    ; SAR: arithmetic right shift = signed divide by a power of 2 (preserves the sign bit)
    mov eax, -16                ; eax = -16 (0xFFFFFFF0)
    sar eax, 2                  ; eax = -4 (0xFFFFFFFC), i.e., -16÷4
    ; SAR vs SHR:
    ; If eax = 0xFFFFFFF0 (-16), SHR yields 0x3FFFFFFC (a very large positive number)
    ; whereas SAR yields 0xFFFFFFFC (-4), preserving the sign bit

    ; The last bit shifted out goes into the CF flag
    mov eax, 5                  ; 0101
    shr eax, 1                  ; eax = 2, CF = 1 (the trailing 1 was shifted out)
    jc carry_was_set            ; If CF=1, the original number was odd

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

Rotate Instructions

Rotate shifts fill the bit shifted out back into the other end, forming a rotation:

InstructionDescription
ROLRotate left (bypasses CF)
RORRotate right (bypasses CF)
RCLRotate left through carry (involves CF)
RCRRotate right through carry (involves CF)

Example

; Rotate shift example

    ; ROL: rotate left
    mov al, 0x85                ; 1000 0101
    rol al, 1                   ; Shift left by 1 bit: 0000 1011
    ; CF = 1 (the most significant bit is shifted out into CF)
    ; At the same time, the original 1 in CF is shifted into the lowest bit, forming a rotation

    ; ROL actual effect: shift left by 1 bit, the most significant bit goes into both CF and the lowest bit
    ; 1000 0101 -> ROL 1 -> 0000 1011

    ; RCL: rotate left through carry (CF participates in the rotation)
    clc                         ; Clear CF = 0
    mov al, 0x85                ; 1000 0101
    rcl al, 1                   ; CF participates: CF bit7...bit0 -> CF
    ; Result: 0000 1010, CF = 1

    ; Rotate shifts are commonly used in encryption algorithms and bit manipulation

Practical Uses of Logical Operations

A comprehensive example — implementing a simple bit-flag system using logical operations:

Example

; File path: bit_flags.asm
; Implementing a bit-flag system using logical operations

section .data
    flags db 0                  ; 8 flag bits, initially all 0
    ; bit0: whether active
    ; bit1: whether visible
    ; bit2: whether needs saving
    ; bit3: whether modified

    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:
    ; Setting flag bits: OR
    mov al, [flags]
    or  al, FLAG_ACTIVE         ; Set bit0
    or  al, FLAG_VISIBLE        ; Set bit1
    ; al = 0000 0011 = 3
    mov [flags], al

    ; Checking flag bits: AND + TEST
    test byte [flags], FLAG_ACTIVE    ; Test whether bit0 is 1
    jnz is_active                     ; ZF=0 means the bit is 1

is_active:
    ; Clearing flag bits: AND + NOT
    mov al, [flags]
    and al, ~FLAG_VISIBLE       ; Clear bit1 (keep other bits unchanged)
    ; al = 0000 0001 = 1
    mov [flags], al

    ; Toggling flag bits: XOR
    mov al, [flags]
    xor al, FLAG_MODIFIED       ; Toggle bit3
    ; If it was 0 it becomes 1, if it was 1 it becomes 0

    mov eax, 1
    mov ebx, 0
    int 0x80

Bit-flag manipulation is extremely common in system programming. OS kernels, device drivers, and embedded systems widely use this technique to manage state.

Other extensions