Concept

A cmp sets flags by subtracting the second operand from the first. Conditional jumps then act on those flags:
- jz / je — jump if zero/equal (result of subtraction was zero).
- jnz / jne — jump if not zero/equal.
- jb — jump if below (unsigned less-than).
- ja, jl, jg, etc. depend on signed/unsigned comparison.

The path not taken (fall-through) is just as important as the jump target.

Example 1: enable_xor check

.text:00414693 cmp     [ebp+enable_xor], 0
.text:00414697 mov     [ebp+var_8], ecx
.text:0041469A mov     [ebp+var_1], bl
.text:0041469D mov     [ebp+var_2], bl
.text:004146A0 mov     [ebp+plaintext_buffer_length], esi
.text:004146A3 jz      short loc_4146B6

jz jumps when enable_xor == 0. So loc_4146B6 is the XOR-disabled branch, and the code after 004146A3 is the XOR-enabled path.

Example 2: Random key loop

enabled_xor:
.text:004146A5 call    _rand
.text:004146AA mov     bh, al
.text:004146AC cmp     bh, 64h
.text:004146AF jb      short enabled_xor

cmp bh, 64h then jb enabled_xor means: if bh < 0x64, loop back. The loop continues until bh >= 0x64.

Takeaway

  • Read cmp a, b as "if a - b ...".
  • jz jumps on equality, not on truthiness.
  • Always label both the jump target and the fall-through path.