Which register does jnz check

Learn which register does jnz check with practical examples, diagrams, and best practices. Covers assembly, x86 development techniques with visual explanations.

Understanding the 'jnz' Instruction in x86 Assembly

A stylized diagram showing CPU registers and a conditional jump arrow, representing the jnz instruction.

Explore the 'jnz' (jump if not zero) instruction in x86 assembly, its functionality, and how it interacts with the CPU's FLAGS register to control program flow.

In x86 assembly language, conditional jump instructions are fundamental for implementing control flow, allowing programs to make decisions and execute different code paths based on the results of previous operations. One such crucial instruction is jnz, which stands for "jump if not zero." Understanding which CPU register jnz checks is key to effectively using it in your assembly programs.

The Role of the FLAGS Register

The jnz instruction, like many other conditional jump instructions in x86 assembly, does not directly check the value of a general-purpose register (like EAX, EBX, etc.). Instead, it inspects a specific bit within the CPU's FLAGS register (also known as EFLAGS or RFLAGS in 64-bit systems). This register is a collection of single-bit flags that reflect the status of the CPU after arithmetic and logical operations.

Specifically, jnz checks the Zero Flag (ZF). The Zero Flag is set (to 1) if the result of an operation is zero, and it is cleared (to 0) if the result is non-zero. The jnz instruction will cause a jump to the specified target address if the Zero Flag is cleared (ZF = 0), meaning the result of the preceding operation was not zero.

flowchart TD
    A[Previous Operation] --> B{Result is Zero?}
    B -- Yes (ZF=1) --> C[Do NOT Jump]
    B -- No (ZF=0) --> D[Jump to Target]

How the Zero Flag (ZF) influences the JNZ instruction

Operations That Affect the Zero Flag

Many x86 instructions implicitly or explicitly modify the FLAGS register, including the Zero Flag. Common instructions that affect ZF and are often followed by jnz include:

  • Arithmetic Instructions: ADD, SUB, INC, DEC, MUL, DIV (results of these operations set or clear ZF).
  • Logical Instructions: AND, OR, XOR, TEST (these instructions perform bitwise operations and set flags based on the result).
  • Comparison Instructions: CMP (this instruction performs a subtraction but discards the result, only setting the flags based on the comparison).

It's crucial to remember that not all instructions affect the flags. For example, MOV instructions typically do not modify the FLAGS register.

section .data
    msg db "Value is not zero!", 0xA, 0xD
    len equ $ - msg

section .text
    global _start

_start:
    mov eax, 10         ; EAX = 10
    sub eax, 10         ; EAX = 0. ZF is set (1).
    jnz skip_print      ; ZF is 1, so jnz does NOT jump.

    ; This code will execute because ZF was set by 'sub eax, 10'
    mov edx, len
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    int 0x80            ; Print "Value is not zero!"

skip_print:
    mov eax, 10         ; EAX = 10
    sub eax, 5          ; EAX = 5. ZF is cleared (0).
    jnz print_again     ; ZF is 0, so jnz WILL jump.

    ; This code will NOT execute
    mov eax, 1
    int 0x80

print_again:
    ; This code will execute because ZF was cleared by 'sub eax, 5'
    mov edx, len
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    int 0x80            ; Print "Value is not zero!" again

    mov eax, 1
    int 0x80            ; Exit

Example demonstrating jnz behavior based on Zero Flag

Common Use Cases for JNZ

jnz is frequently used in loops and conditional statements. For instance, it can be used to iterate until a counter reaches zero, or to check if a function returned a non-zero error code. A common pattern involves using DEC to decrement a counter and then jnz to loop if the counter is not yet zero.

section .text
    global _start

_start:
    mov ecx, 5          ; Initialize loop counter

loop_start:
    ; Do some work here
    ; ...

    dec ecx             ; Decrement counter. This affects ZF.
    jnz loop_start      ; If ECX is not zero (ZF=0), jump back to loop_start.

    ; Loop finishes when ECX becomes zero
    mov eax, 1
    int 0x80

Using DEC and JNZ for a simple loop