0%

[Opcode] JMP 轉成機械碼的原理與過程

前言

JMP 指令根據跳轉目的地遠近分成短跳轉 (Short jump)、近跳轉 (Near jump)、遠跳轉 (Far jump)、他們所代表的含意不一樣,使得機械碼 opcode 呈現的方式也不一樣。

閱讀手冊

引用指令手冊(Intel® 64 and IA-32 Architectures Software Developer's Manual)裡面一些對於 JMP 的敘述:

  1. Short jump—A near jump where the jump range is limited to –128 to +127 from the current EIP value.
  2. Near jump—A jump to an instruction within the current code segment (the segment currently pointed to by the CS register), sometimes referred to as an intrasegment jump.
  3. Far jump—A jump to an instruction located in a different segment than the current code segment but at the same privilege level, sometimes referred to as an intersegment jump.

它們主要是以所要跳的目的地位址與現在的 IP (instruction pointer) 位址差值來區分:

  1. 短跳轉:差值在 -128 ~ +127 (8-bit) 之內。
  2. 近跳轉:目的地在同一個區段內,且差值在 32-bit 可以表示的範圍內,又稱段內跳轉。
  3. 遠跳轉:目的地在別的區段,又稱段間跳轉。

雖然在組合語言都是以 JMP 來實現跳轉,但在組譯轉成 opcode 時翻譯出來的卻不一樣,短跳轉 (EB)、近跳轉 (E9)、遠跳轉 (EA)。當然,opcode 不一樣就代表是不同的指令,其後的參數要怎麼給是該瞭解的事情。參考手冊說明摘要如下:

Jump Opcode Instruction
Short Jump EB cb JMP rel8
Near Jump E9 cw/cd JMP rel16/rel32
Far Jump EA cd/cp JMP ptr16:16/ptr16:32

參數解釋

  1. rel8/rel16/rel32:偏移量(也就是上面提到的差值)能用有號 8/16/32-bit 來表示的相對位址。
  2. ptr16:16/ptr16:32:一個相對遠的指標 (pointer),通常與 IP 不同區段,前面的 16/16 表示 16-bit 的區段暫存器,後面的 16/32 表示目的地在那個區段的偏移量。
  3. cb/cw/cd/cp:用來描述代碼的偏移量和新的區段暫存器的值,分別為 1-byte、2-byte、4-byte、6-byte。

程式驗證

有概念之後,用程式來對上面敘述做驗證吧:

短跳轉

Address Opcode Instruction
003F1010 EB 06 JMP 003F1018
003F1012 EB 04 JMP 003F1018
003F1014 EB 02 JMP 003F1018

因為指令位址距目的很近,所以為短跳轉 (EB),EB 後的數字為目的地與 EIP 的偏移量,但可能有人會問,為什麼對不起來?

像是第一個的 偏移量 = 003F1018h - 003F1010h = 08h 結果不是 EB 08,而是 EB 06 。這是因為 CPU 在運作時,看到 EB 06 知道要跳轉,也由於它已經讀了這一指令,EIP 會再加 2 指向下一指令,再執行 EB 06 這個指令。可以看得出關鍵嗎?在執行 EB 06EIP 已經又加 2 了,實際上的算法應為 偏移量 = 003F1018h - (003F1010h + opcode的長度) = 06h

近跳轉

Address Opcode Instruction
013D1035 E9 85 00 00 00 JMP 013D10BF
013D103A E9 80 00 00 00 JMP 013D10BF
013D103F EB 7E JMP 013D10BF

偏移量的算法和短跳轉相同,不同在於近跳轉的 opcode 且 E9 與長度為 5-byte,在計算時要注意。在此特地用跳轉至同目的地但分別為近跳轉與短跳轉來說明,當從 1-byte 的 7E 要進位到 80 時,就會變成 4-byte 的 00 00 00 80h,因為其超出有號 8-bit 可表示範圍。

很高興能在這裡幫助到您,歡迎登入 Liker 為我鼓掌 5 次,或者成為我的讚賞公民,鼓勵我繼續創造優質文章。
以最優質的內容回應您的鼓勵