x86 loope/z instruction should be sign extended according to address size prefix

Hey I’m wondering if the LOOPE LOOPZ instructions should be sign extended by the address size prefix.

In the intel manual it’s written:

Performs a loop operation using the RCX, ECX or CX register as a
counter (depending on whether address size is 64 bits, 32 bits, or 16
bits). Note that the LOOP instruction ignores REX.W; but 64-bit
address size can be over-ridden using a 67H prefix.


IF (AddressSize = 32)
    THEN Count is ECX;
ELSE IF (AddressSize = 64)
    Count is RCX;
ELSE Count is CX;

Now I understand what register we use for counting will be dependent on the address size prefix, but nothing on the validity of the assembly written is mentioned, seeing disassemblers output like objdump and others yields for the current stream of bytes 67 e1 d2 the following output

0:  67 e1 d2                addr32 loope 0xffffffffffffffd5

I thought it should extend the immediate to the size of the counter so it should have looked something like this:

0:  67 e1 d2                addr32 loope 0xffffffd5

So I’m basically just asking about the validity of the assembly on how it should be written depending on the mode of operation (bitness).

>Solution :

The immediate is the branch target DESTination, a pc-relative encoding of the distance to branch, should the branch be taken.  Positive values indicate forward branching in the instruction stream and negative values indicate backward branching.

The branch condition is whether the designated register is zero or not; that register (some version of cx) is not sign extended — it is just compared with zero.

The sign extension is of the branch target immediate has the effect of determining whether the branch is forward or backward.  The size of the branch target immediate is not determined by the size prefix — the size prefix determines the register width to use in the compare with zero.

Leave a Reply