Сборка x86 - кодирование относительного jmp

Меня немного смущает то, как gcc кодирует относительные переходы. У меня есть следующее:

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

    return 0;
}

Строим это (gcc -c -o test.o test.c) показывает следующее (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 шоу jmp 2Это означает, что переход выполняется со смещением 2. Теперь я понял, что смещения относительных переходов добавляются к текущему значению eip, который должен указывать на следующую инструкцию (т.е. nop). Эта кодировка заставляет меня думать, что смещение относительно адреса jmp сам. Не должен jmp быть закодирован как jmp 0, поскольку nop уже в label?

1 ответ

Решение

Кодируется со смещением 0:

eb 00

Однако принято абстрагироваться от таких деталей кодирования в сборке (и, следовательно, выводить дизассемблер) и обозначить относительные переходы со смещением относительно начала инструкции (например, $+2) или абсолютно (как в jmp 6 <label>).

Другие вопросы по тегам