How encode a relative short jmp in x86

assembly, instruction-encoding, x86, x86-64

Solution

The `rel8` is relative to the next instruction's memory address, as can easily be confirmed by creating two executables and disassembling them:

@label:
    jmp @label
    nop

This disassembles as (with ndisasm, it's the same in 16-bit, 32-bit and 64-bit code):

EBFE jmp short 0x0
90   nop

Then, another executable:

    jmp @label
@label:
    nop

EB00 jmp short 0x2
90   nop

So, the `rel8` is encoded always relative to the next instruction after `jmp`. Disassemblers (at least`ndisasm` and `udcli`), however, show it relative to the `jmp` instruction itself. That may possibly cause some confusion.

Problem

Suppose I want to do a short jump using the EB opcode, `jmp rel8` short jump Intel manual entry for it: EB CB or JMP rel8 "Jump short, RIP = RIP + 8-bit displacement sign extended to 64-bits" (where CB is a byte signed value representing the relative offset relating to direction in EIP register) Maybe always the offset will be offset+2 because the EIP in execution time (the reference direction) in this short jump is the base of the twobyte instruction, but the addend occurs always - `eb 30` = `jmp 0x00000032 (+30)` - `eb e2` = `jmp 0xffffffe4 (-30)` then EIP can be intentionally the same direction because fe + 2 is 00 or EIP. - `eb fe` = `jmp 0x00000000` I find it surprising that the overoffset occurred bifurcated although the number is negative. But in the Intel I find no mention (maybe because 3000 pages). Intel® 64 and IA-32 Architectures Software Developer’s Manual: Vol. 2A 3-423 A near jump where the jump range is limited to –128 to +127 from the current EIP value. Then I contemplate three possibilities: - is +2 because is the after/future value of EIP in execution time - The coded value is not a 2s component encoded signed number. - this appears in the manual but I have not seen because i'm stupid

Original source