2013-02-15 61 views
13

假設我想用下面的操作碼做一個短跳轉:如何編碼在x86的相對短JMP

EBCBJMP發佈8

「跳轉短,RIP = RIP + 8位移位符號 擴展到64位「

(其中CB是字節有符號值表示與方向EIP寄存器)

也許始終偏移將是相對偏移偏移+ 2因爲(EIP的執行時間基準方向)在這個短跳躍的基的twobyte指令,但加數occurs always

EB 30 = JMP 0x00000032(30)

EB E2 = JMP 0xffffffe4(-30)

然後EIP可以故意地是相同的方向,因爲fe + 2是或EIP

EB FE = JMP 00000000

我覺得奇怪的是,overoffset內容時發生分叉,雖然數量是負的。但在英特爾我沒有發現(也許是因爲3000頁)。

英特爾®64和IA-32體系結構 軟件開發人員手冊:卷。圖2A 3-423

的近跳,其中跳轉範圍是從當前 EIP值不限於-128至127

然後我考慮三種可能性:

  1. 是2因爲是後在執行時間EIP的/未來值
  2. 的編碼值不是編碼的2S部件簽署數。
  3. 這似乎在手冊中,但我還沒有看到,因爲我傻

回答

11

rel8是相對於下一個指令的存儲器地址,因爲可以很容易地通過創建兩個可執行和拆卸它們予以確認:

@label: 
    jmp @label 
    nop 

這拆解如(與ndisasm,它在16位是相同的, 32位和64位代碼):

EBFE jmp short 0x0 
90 nop 

然後,另一個可執行:

jmp @label 
@label: 
    nop 

EB00 jmp short 0x2 
90 nop 

因此,rel8總是相對於jmp之後的下一條指令進行編碼。然而,反彙編器(至少ndisasmudcli)顯示它相對於jmp指令本身。這可能會導致一些混淆。

14

無論是短跳與否,它總是destination - source + sizeof(opcode)。在你的情況下(無條件短跳轉),sizeof(opcode)是2.這個增加的原因是因爲一旦cpu執行了取指令階段,指令指針就會指向分支之後的指令。

+0

我很困惑的術語:什麼是「短跳」?我一直無法在網絡上的任何地方找到這個定義。 – 2013-02-20 19:30:40

+2

@AndersonGreen短跳轉編碼爲* jmp rel8 *(EB XX),其中相對距離(dest-source)小於0x80。另一個叫做跳遠,它編碼爲* jmp rel32 *(E9 XXXXXXXX)。請注意,這可以使用66H前綴進行編碼,這會將操作數更改爲* rel16 *。 – JosephH 2013-02-21 06:24:28

4

跳轉指令相對於跳轉指令的結束(它是兩個字節長)需要一個EIP,並且需要一個字節的操作數,它是符號擴展並添加到EIP。