How encode a relative short jmp in x86

18

Suppose I want to do a short jump using the following opcodes:

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 ocurred 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:

  1. is +2 because is the after/future value of EIP in execution time
  2. The coded value is not a 2s component encoded signed number.
  3. this appears in the manual but I have not seen because i'm stupid
assembly
x86
x86-64
asked on Stack Overflow Feb 15, 2013 by user1629569 • edited Apr 17, 2019 by 1201ProgramAlarm

3 Answers

18

Whether it's short jump or not, it's always destination - (source + sizeof(instruction)).

i.e. dst - end_of_jmp

In your case (short jump), sizeof(instruction) is 2.

The reason behind this addition is because of the fact that once the cpu has performed the instruction fetch stage, the instruction pointer is already pointing to the instruction that comes after the branch. The rel8 or rel32 branch displacement is relative to that EIP/RIP value.

answered on Stack Overflow Feb 15, 2013 by JosephH • edited Apr 17, 2019 by Peter Cordes
17

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 leastndisasm and udcli), however, show it relative to the jmp instruction itself. That may possibly cause some confusion.

answered on Stack Overflow Feb 15, 2013 by nrz
6

The jump short takes an EIP relative to the end of the jump instruction (which is two bytes long), and takes a one byte operand, which is sign extended and added to EIP.

answered on Stack Overflow Feb 15, 2013 by SecurityMatt

User contributions licensed under CC BY-SA 3.0