Инструкция JMP — шестнадцатеричный код

Есть сомнения относительно преобразования шестнадцатеричного кода машинной инструкции JMP. У меня есть абсолютный адрес, на который я хочу перейти, скажем, «JMP 0x400835». Во-первых, разрешено ли это? Если да, каким будет соответствующий шестнадцатеричный код? Если нет, могу ли я сначала сохранить адрес в каком-нибудь регистре, скажем, EAX, а затем поставить «JMP EAX»? Я работаю над архитектурой x86 (64b).

Я попытался распечатать шестнадцатеричный код из вывода diassem в gdb, но согласованности нет, т. е. я не вижу адреса назначения в шестнадцатеричном коде.

Я новичок в шестнадцатеричном коде и машинных инструкциях, так что извините за невежество.


person Deepanjan Mazumdar    schedule 22.03.2012    source источник
comment
Связано: Как написать абсолютную цель для почти прямого относительного вызова/jmp в MASM. Если цель перехода находится в диапазоне, некоторые цепочки инструментов (например, NASM + ld в Linux) будут собирать + связывать jmp с абсолютным адресом как относительный jmp из известного адреса (в коде, зависящем от положения).   -  person Peter Cordes    schedule 21.12.2018


Ответы (2)


В 64-битном режиме нет перехода формы JMP absaddr на абсолютный адрес. Операнд перехода всегда представляет собой 32-битное относительное смещение к rip, которое расширяет знак до 64-битного.

Причина, по которой вы не видите согласованности, возможно, заключается в том, что смещение зависит от текущего указателя инструкции, а вы этого не распознали.

jmp eax также не допускается, поскольку адреса, конечно, всегда имеют ширину 64 бита в 64-битной архитектуре. Возможна последовательность mov rax, addr + jmp rax, она будет выглядеть так

48 c7 c0 35 08 40 00            mov rax, 0x00400835
ff e0                           jmp rax

or

48 b8 35 08 40 00 00 00 00 00   mov rax, 0x0000000000400835
ff e0                           jmp rax

Как я узнал эти шестнадцатеричные коды? Ну, я спросил своего компилятора. Я компилировал с помощью gcc -c и дизассемблировал с помощью objdump. Я не стал использовать синтаксис Intel, потому что он мне не нужен. Итак, это синтаксис AT&T.

echo 'asm("mov $400835, %rax\n jmp *%rax\n");' > test.c
gcc -c test.c
objdump -d test.o
person Gunther Piez    schedule 22.03.2012
comment
Спасибо за ответ. Это действительно помогло мне. objdump действительно хороший инструмент! - person Deepanjan Mazumdar; 24.03.2012
comment
Эй.. Я отметил ваш пост как полезный.. я думаю, это то, что нужно, верно? - person Deepanjan Mazumdar; 25.03.2012
comment
Вы имеете в виду, что jmp absaddr будет jmp %rip + absaddr (где absaddr должен быть равен или меньше 32 бит)? - person Man of One Way; 03.07.2014
comment
@ManofOneWay Не уверен, что вы пытаетесь спросить, поскольку jmp absaddr не существует, а jmp %rip+absaddr не является абсолютным. Если вы скажете ассемблеру преобразовать некоторый код в вид jmp someaddr, он рассчитает относительное расстояние от текущего адреса (который позже будет в %rip) до someaddr и выдаст e9 xx xx xx xx, где четыре xx байта соответствуют рассчитанному разница адресов. - person Gunther Piez; 06.07.2014
comment
Здесь вы пишете jmp *%rax. Не могли бы вы сказать, где я могу найти описание этого синтаксиса? Поскольку везде объясняется синтаксис AT&T, этот синтаксис JMP не указан. - person Kibernetik; 15.01.2015
comment
mov eax, 0x00400835/mov $0x00400835, %eax всего 5 байт. Нет никакой выгоды в расширении этого непосредственного знака с помощью 64-битного mov вместо того, чтобы полагаться на неявное нулевое расширение от записи EAX. Почему инструкции x86-64 в 32-битных регистрах обнуляют верхнюю часть полного 64-битного регистра? - person Peter Cordes; 21.12.2018

Если вы по какой-либо причине не хотите использовать регистр, также можно закодировать 64-битный абсолютный немедленный переход как

ff 25 00 00 00 00           jmp qword ptr [rip]      jmp *(%rip)
yo ur ad dr re ss he re     some random assembly

rip относится к указателю инструкции ПОСЛЕ самой инструкции jmp, поэтому это указатель на ваш адрес.

person Artikash-Reinstate Monica    schedule 20.12.2018