jmp 指令

jmp指令 

解釋:

n       jmp爲無條件轉移,可以只修改IP,也可以同時修改CS和IP;

n       jmp指令要給出兩種信息:

n       轉移的目的地址

n       轉移的距離(段間轉移、段內短轉移,段內近轉移)

格式:

一.Jump short 標號

   這種格式的 jmp 指令實現的是段內短轉移,它對IP的修改範圍爲 -128~127,也就是說,它向前轉移時可以最多越過128個字節,向後轉移可以最多越過127個字節。

 

示例:

assume cs:codesg

codesg segment

  start:mov ax,0

          jmp short s

          add ax,1

       s:inc ax

codesg ends

end start

 

說明:上面的程序執行後, ax中的值爲 1 ,因爲執行  jmp short s 後 ,越過了add ax,1 ,IP 指向了標號 s處的 inc ax。也就是說,程序只進行了一次ax加1操作。

 

注意:

n       彙編指令jmp short s 對應的機器指令應該是什麼樣的呢?

n       我們先看一下別的彙編指令和其對應的機器指令

 

 

可以看到,在一般的彙編指令中,彙編指令中的idata(立即數),不論它是表示一個數據還是內存單元的偏移地址,都會在對應的機器指令中出現,因爲CPU執行的是機器指令,它必須要處理這些數據或地址。

 

n       但是:當我們查看jmp short s或jmp 0008所對應的機器碼,卻發現了問題。

 

看到了嗎?機器碼中並不含有立即數。爲什麼呢,解釋如下

n       在“jmp short 標號”指令所對應的機器碼中,並不包含轉移的目的地址,而包含的是轉移的位移。

n       這個位移,使編譯器根據彙編指令中的“標號”計算出來的。

如果我們在第一行程序後加上Mov bx,0000,你會發器機器碼沒變,還是EB03,爲什麼呢?jmp 0008對應的偏移就是0003大家可以回憶一下cpu中指令的執行流程,就會發現當執行完EB03後,ip=ip+2=0005,大家注意看EB03後面有個03,表示再向後三個單位,這樣就到了0008這個偏移處了。所以我們說包含 的是轉移的位移。

 

轉移位移具體的計算方法如下圖

 

 

 

二.還有一種和指令“jmp short 標號”功能相近的指令格式:

    jump near ptr 標號

    實現的時段內近轉移。

指令“jmp near ptr 標號”的功能爲:(IP)=(IP)+16位位移。

n           指令“jmp near ptr 標號”的說明:

n                 (1)16位位移=“標號”處的地址-jmp指令後的第一個字節的地址;

n                 (2)near ptr指明此處的位移爲16位位移,進行的是段內近轉移;

n                 (3)16位位移的範圍爲

   -32769~32767,用補碼錶示;

n                 (4)16位位移由編譯程序在編譯時算出。

我們發現jump short 標號與jump near ptr 標號非常相似,不同點在哪兒呢?實際上就是跳轉的範圍,看下面一段代碼:

assume cs:codesg

codesg segment

  start:mov ax,0

          jmp near ptr s

          add ax,1

         dw 200 dup(2)此處表示生成若干條彙編指令,從而產生多個地址,方便測試

          s:inc ax

codesg ends

end start

 

如果我們將此處的jmp near ptr s 改爲jmp short s,那麼編譯時會報這樣的錯誤 jump out of range by 276 bytes,即jump越界了。也就是說:

在編譯的時候由編譯程序算出是8位還是16位位移。8位位移的範圍是2的7次方,而16位位移的範圍是2的15次方。

 

三.回顧前面講的jmp指令,其對應的機器碼中並沒有轉移的目的地址,而是相對於當前IP的轉移位移。

指令 “jmp far ptr 標號”

   實現的是段間轉移,又稱爲遠轉移

n       指令 “jmp far ptr 標號” 功能如下:

n       (CS)=標號所在段的段地址;

n       (IP)=標號所在段中的偏移地址。

n       far ptr指明瞭指令用標號的段地址和偏移地址修改CS和IP。

實例:

assume cs:codesg

           codesg segment

           start:mov ax,0

                     mov bx,0

               jmp far ptr  s

               db 256 dup (0)

               s: add ax,1

                 inc ax

           codesg ends

           end start

分析:用U命令查看後如圖:

 

“0B 01 BD 0B” 是目的地址在指令中的存儲順序,高地址的“BD 0B”是轉移的段地址:0BBDH,低地址的“0B 01” 是偏移地址:010BH。看到了嗎?標號所在的段地址與偏移地址爲:0BBD:010B,可能是位於另一個代碼段中。

前面三者的區別,我用代碼總結一下,大家一看就明白了:

jmp   short   xxx和jmp   near   ptr   xxx可以寫成jmp   xx   
  例如:   。。。   
  jmp   exit   
  。。。   
        exit: mov   ax,4c00h   
        int   21h   
  。。。   

 2.jmp   far   ptr   xxx   
        code1   segment   
  。。。   
  jmp far   ptr   new_seg   
  。。。   
        code1 ends   
        code2 segment   
  。。。   
        new_seg:   
  。。。   
        code2 ends  

 

現在我們再來看第四種:

四.先看代碼,再來闡述:

JMP   DWORD   PTR   XXXX是段間間接尋址   
  由xxxx的尋址方式求得偏移地址(假如是adress後),【adress】和【adress+2】分別就是轉移目的地址得偏移地址和段地址   
  還是舉個例吧:   
  code1 segment   
  。。。   
  jmp dword   ptr   [bx][di]   
  。。。   
  code1 ends   
  code2 segment   
  。。。   
  jmp_here:   
  。。。   
  code2 ends   
  設(ds)=1000h,(di)=0300h,(bx)=0150h,則adress=10000h+150h+300h=10450h,即轉移目的地址jmp_here的值存放在以10450h地址開始的4個字節中   
    
  jmp   word   ptr   adress是段內間接尋址

明白了吧,代碼已經描述得很清楚了。

現在,關於jump的用法用一個圖全部總結一下:

 

 

 

 

 

 

 

 

 

格式

描述

舉例

類別

說明

jmp 16位寄存器

以16位寄存器的值改變IP

jmp ax

段內轉移

 

jmp 段地址:偏移地址

以立即數改變段地址和偏移地址

jmp 0045H:0020H

段間轉移

 

jmp short 標號

以標號地址後第一個字節的地址來改變IP,實際上這個功能可以作如下描述:
(IP)=(IP)+8bit位移
8bit位移指的是從jmp指令後第一個字節開始算起

jmp short sign

段內短轉移

對IP的修改範圍是-128->127,實際算法是編譯器根據當前IP指針的指向來計算到底偏移多少個字節來指向下一條指令,下面這段代碼就會出編譯錯誤
jmp short s
dw 200 dup(2)
s: mov ax,4
因爲跳轉超過了範圍

jmp near ptr 標號

以標號地址後第一個字的地址來改變IP,
實際上這個功能可以作如下描述:
(IP)=(IP)+16bit位移
16bit位移指的是從jmp指令後第一個字節開始算起

jmp near ptr sign

段內近轉移

對IP的修改範圍是-32768->32767

jmp far ptr標號

以標號的段地址和指令地址同時改變CS和IP

jmp far ptr sign

段間轉移

 

jmp word ptr 內存地址

以內存地址單元處的字修改IP,內存單元可以以任何合法的方式給出

jmp word ptr ds:[si]
jmp word ptr ds:[0]
jmp word ptr [bx]
jmp word ptr [bp+si+idata]

段內轉移

 

jmp dword ptr內存地址

以內存地址單元處的雙字來修改指令,高地址內容修改CS,低地址內容修改IP,內存地址可以以任何合法的方式給出

jmp dword ptr [bx]

段間轉移

s1 segment
dw 0a0bh, 0c0dh
s1 ends

mov ax,s1
mov ds,ax
jmp dword ptr ds:[0]

 

 

前面我們講到了,jmp是指無條件的跳轉,我們知道,在c,或java或c#中總會存在這樣或那樣的條件判斷,那麼彙編中如何進行有條件的跳轉呢?

1. jcxz指令 jcxz指令爲有條件轉移指令,所有的有條件轉移指令都是短轉移,在對應的機器碼中包含轉移的位移,而不是目的地址。對IP的修改範圍都爲-128~127。

指令格式:jcxz 標號 

   (如果(cx)=0,則轉移到標號處執行。)

 

 

2.含義:

n       jcxz 標號 指令操作:

n       當(cx)=0時,(IP)=(IP)+8位位移)

n       8位位移=“標號”處的地址-jcxz指令後的第一個字節的地址;

n       8位位移的範圍爲-128~127,用補碼錶示;

n       8位位移由編譯程序在編譯時算出。

n       當(cx)=0時,什麼也不做(程序向下執行)。

 3.實例:

我們從 jcxz的功能中可以看出,指令“jcxz 標號”的功能相當於:

   if((cx)==0)jmp short 標號;

 (這種用C語言和彙編語言進行的綜合描述,或許能使你對有條件指令理解得更加清楚。)

 

當然,有條件的跳轉還有其它多種情況,不過原理是一樣的。現在我們再來看看破解外掛中常用的循環指令:loop

n       loop指令爲循環指令,所有的循環指令都是短轉移,在對應的機器碼中包含轉移的位移,而不是目的地址。對IP的修改範圍都爲-128~127。

n       指令格式:loop 標號

    ((cx))=(cx)-1,如果(cx)≠0,轉移到標號處執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章