2012-03-22 289 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