Skip to content

[General]: JCXZ and JECXZ can choose the wrong branch by testing the wrong register bits #28

Description

@shuklaayush

Problem

JCXZ and JECXZ jump only when a particular register is zero. JCXZ must test CX, the low
16 bits of RCX. JECXZ must test ECX, the low 32 bits. The published source sometimes
tests 8 or 64 bits instead. This can make the instruction jump when it should continue,
or continue when it should jump.

For example, in 64-bit mode RCX can be nonzero while its low 32 bits are zero. JECXZ
should jump in that case. The source tests all 64 bits and does not jump.

The source passes a size named operand_size to Instr_JCXZ, which uses it
to choose how many register bits to test. It passes 8 for JCXZ and the JECXZ form used
outside 64-bit mode, and 64 for JECXZ in 64-bit mode. The correct sizes are 16 and 32
respectively. The separate 8-bit value encoded in the instruction tells it how far to
jump; it does not determine the register width.

The forms share opcode E3; the XML does not state which address size selects each one.
This report identifies them by their XED form names (JCXZ, JECXZ, JRCXZ) and uses the
valid32/valid64 attributes to distinguish the two JECXZ forms.

Reproducing cases

JECXZ in 64-bit mode

Set RCX to 0x0000000100000000 and execute bytes 67 E3 02. The 67 prefix selects
the 32-bit count register, ECX. The final byte, 02, means jump two bytes beyond the
end of this instruction.

Value being tested Value Is it zero?
ECX, the low 32 bits required by JECXZ 0x00000000 Yes
RCX, the full 64 bits tested by the source 0x0000000100000000 No

Expected: take the jump. Source: continue with the next instruction.

JCXZ in 32-bit mode

Set ECX to 0x00000100 and execute the same bytes, 67 E3 02. In this mode the prefix
selects the 16-bit count register, CX.

Expected: do not jump, because CX is 0x0100, which is nonzero. Source: jump,
because it tests only the low eight bits, which are zero.

Source checked: Intel SDM executable specification revision
d307f89f742765865b87c5d4d23f552b3c72e871.

Manual reference

Intel SDM Volume 2A, 253666-092US, June 2026, Jcc, page 3-502 (PDF page 620)
states that address size selects CX, ECX or RCX for this branch family.

Proposed fix

Use 16 for JCXZ and 32 for both JECXZ forms when calling Instr_JCXZ. Update the
corresponding size information in those source entries. Keep the jump-distance field at
eight bits. JRCXZ, the variant that tests all 64 bits of RCX, should remain unchanged.

The example follows from the published source and manual; it does not claim an Intel
hardware test.

AI disclosure

Assisted-by: Codex

Codex assisted with source analysis, the proposed correction, and drafting this report.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions