assemblyx86disassemblyobjdumpradare2

x86 assembly - Encoding a relative jmp


I'm a bit confused by how gcc encodes relative jumps. I have the following:

int main(void)
{
    __asm__ __volatile__(
        "jmp label\n"
        "label:\n"
        "nop\n"
    );

    return 0;
}

Building this (gcc -c -o test.o test.c) shows the following (objdump -M intel -d test.o):

0000000000000000 <main>:
   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
   4:   eb 00                   jmp    6 <label>

0000000000000006 <label>:
   6:   90                      nop
   ...

rasm2 -d eb00 shows jmp 2, which means the jump is being performed with an offset of 2. Now, I had understood that relative jumps' offsets are added to the current value of eip, which should be pointing at the next instruction (i.e. nop). This encoding makes me think that the offset is relative to the address of the jmp itself. Shouldn't the jmp be encoded as jmp 0, since nop is already at label?


Solution

  • It is encoded with an offset of 0:

    eb 00
    

    However it is customary to abstract away from such encoding details in assembly (and therefore disassembler output) and denote relative jumps with an offset relative to the start of the instruction (eg $+2) or absolutely (as in jmp 6 <label>).