Assembly JMP指令-十六进制代码

Assembly JMP指令-十六进制代码,assembly,hex,x86-64,machine-code,Assembly,Hex,X86 64,Machine Code,对JMP机器指令的十六进制代码转换有疑问。我有我想要跳转到的绝对地址,比如“JMP 0x400835”。 首先,这是允许的吗?如果是,对应的十六进制代码是什么? 如果没有,我可以先将地址存储在某个寄存器中,比如EAX,然后放入“JMP EAX”吗? 我正在研究x86(64b)体系结构 我已经尝试从gdb中的diassem输出打印十六进制代码,但是没有一致性,即,我在十六进制代码中没有看到目标地址 我不熟悉十六进制代码和机器指令,所以请原谅我的无知。在64位模式下,格式JMP absaddr不会跳

对JMP机器指令的十六进制代码转换有疑问。我有我想要跳转到的绝对地址,比如“JMP 0x400835”。 首先,这是允许的吗?如果是,对应的十六进制代码是什么? 如果没有,我可以先将地址存储在某个寄存器中,比如EAX,然后放入“JMP EAX”吗? 我正在研究x86(64b)体系结构

我已经尝试从gdb中的diassem输出打印十六进制代码,但是没有一致性,即,我在十六进制代码中没有看到目标地址


我不熟悉十六进制代码和机器指令,所以请原谅我的无知。

在64位模式下,格式
JMP absaddr
不会跳转到绝对地址。跳转的操作数始终是相对于
rip
的32位相对位移,其符号扩展为64位

您看不到一致性的原因可能是偏移量取决于当前指令指针的大小,而您没有意识到这一点

jmp eax
也不允许,因为在64位体系结构中,地址当然总是64位宽。一个序列
mov-rax,addr+jmp-rax
是可能的,它看起来像

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

我是怎么知道这些十六进制代码的?我问过我的编译器。我用
gcc-c
编译,用
objdump
反汇编。我没有费心使用英特尔语法,因为我不需要它。这就是AT&T的语法

echo 'asm("mov $400835, %rax\n jmp *%rax\n");' > test.c
gcc -c test.c
objdump -d test.o

如果出于任何原因不想使用寄存器,也可以将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指令本身之后的指令指针,因此它是指向您地址的指针。

谢谢您的回答。这真的帮助了我。objdump是一个非常好的工具!嘿我已将你的帖子标记为“有用”。。我想这就是需要的,对吧?你的意思是“jmp absaddr”将是“jmp%rip+absaddr”(其中absaddr必须等于或小于32位)?@Manofonway也不确定你想问什么,因为没有
jmp absaddr
jmp%rip+absaddr
不是绝对的。如果您告诉汇编程序以
jmp someaddr
的形式翻译某些代码,它将计算从当前地址(稍后执行时将在
%rip
中)到
someaddr
的相对距离,并发出
e9 xx xx xx xx
,其中,四个xx字节对应于计算的地址差。在这里,您将写入“jmp*%rax”。你能告诉我在哪里可以找到这个语法的描述吗?因为到处都解释了AT&T语法,所以未列出此JMP语法。相关:。如果跳转目标在范围内,一些工具链(例如Linux上的NASM+
ld
)会将jmp组装并链接到绝对地址,作为已知地址(位置相关代码)的相对jmp。
ff 25 00 00 00 00           jmp qword ptr [rip]      jmp *(%rip)
yo ur ad dr re ss he re     some random assembly