Сборка 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>
).