2012-03-22 233 views
12

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

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

我是新来的十六进制代码和机器指令,所以请原谅我的无知。

回答

23

在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 

48 b8 35 08 40 00 00 00 00 00 mov rax, 0x0000000000400835 
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 
+0

谢谢你的回答。这真的帮助了我。 objdump是一个很好的工具! – 2012-03-24 00:12:11

+0

嘿..我已经标记你的帖子为“有用”..这就是我所需要的,我猜对吧? – 2012-03-25 19:58:11

+0

@DeepanjanMazumdar你需要点击勾号 – hirschhornsalz 2012-03-25 20:33:40