可以修改IP寄存器的值,或者同時修改CS與IP的值的指令稱為轉移指令。轉移指令的功能就是使得CPU執行內存中某段特定的指令或程序。
8086CPU的轉移行為分為如下幾類;
1.只改變IP值,稱為段內轉移。比如 jmp ax;段內轉移又分為短轉移和近轉移。短轉移IP的修改范圍為-128~127,近轉移IP的修改范圍為-32768~32767.
2.同時改變CS:IP的值稱為段間轉移。比如 jmp 1000:0
8086CPU的轉移指令分為如下幾種:
無條件轉移指令:jmp
條件轉移指令
循環指令
過程
中斷
本次博文主要介紹jmp指令
9.1 操作符offset
offset為偽指令,該指令由編譯器解釋。offset的作用是取得標號的偏移地址.比如:
assume cs:codesg codesg segment start: mov ax,offset start 含義:相當於mov ax,0 s: mov ax,offset s 含義:相當於mov ax,3 codesg ends end start
9.2 jmp指令
jmp為無條件轉移指令,可以只修改IP寄存器的值,也可以同時修改CS與IP的值。
jmp指令要給出兩種信息:
(1)轉移的目的地址
(2)轉移的距離(段間轉移,段內短轉移,段內近轉移)
9.3依據位移進行轉移的jmp指令
jmp short 標號(轉到標號處執行指令)
這裡short代表的是段內短轉移,向前可轉移128個字節,向後可轉移127個字節。
標號代表目的地址。
指令結束後,cs:ip指向標號處的指令
這裡需要說明一點:
有如下代碼段:
代碼段1:
assume cs:codesg
codesg segment
start:mov ax,0
jmp short s
add ax,1
s:inc ax
codesg ends
end start
代碼段2:
assume cs:codesg
codesg segment
start:mov ax,0
mov bx,0
jmp short s
add ax,1
s:inc ax
codesg ends
end start
代碼段1和代碼段2翻譯成機器碼:兩個代碼段的中jmp short s指令的機器指令分別為:
機器碼 匯編指令
代碼段1: EB03 JMP 0008
代碼段2: EB03 JMP 000B
可以看出匯編指令的0008和000B分別為兩個代碼段中s標號的偏移地址,然而兩個代碼段中jmp short s對應的機器碼都是一樣的,均為EB03.說明機器碼中並不包含跳轉的目的地址。
其實錯了其中 EB03中的03即為將要跳轉的標號處的地址為當前IP值加3.
所以 jmp short 標號 的跳轉是根據當前IP值與標號處指令地址的偏移值進行跳轉的
9.4轉移的目的地址在指令中的jmp指令
jmp far ptr 標號 實現段間轉移
功能為:CS=標號處的段地址 IP=標號處的偏移地址
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
翻譯成機器碼:
jmp far ptr s的匯編為jmp 14FF:010B 機器碼為EA0B01FF14 可以看出匯編指令和機器碼中均包含了段地址14FF和偏移地址010B
9.5轉移地址在寄存器中的jmp指令
比如jmp ax 這很容易理解,即將IP的值改為AX寄存器中存儲的值進而實現跳轉
9.6轉移地址在內存中的jmp指令
jmp word ptr 內存地址(段內轉移)
比如:
mov ax,0123h
mov ds:[0],ax
jmp word ptr ds:[0]
其含義為 IP=0123H
再比如:
mov ax,0123h
mov [bx],ax 含義:((ds)*16+(bx))=(ax)
jmp word ptr [bx]
此時IP=0123h
jmp dword ptr 內存地址(段間轉移) 高地址的字存放段地址,低地址的字存放偏移地址
(CS)=(內存地址+2)
(IP)=(內存地址)
比如:
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
此時(CS)=0000H,(IP)=0123H
又比如:
mov ax,0123h
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr [bx]
此時(CS)=0000H,(IP)=0123H
9.7 jcxz指令
jcxz指令為有條件轉移指令,所有有條件轉移指令都為段內段轉移指令
指令格式:
jcxz 標號(如果(cx)=0,則轉移到標號處執行)
可以這樣理解:
if((cx)==0) jmp short s
9.8 loop指令
loop為循環指令,所有的循環指令均為段內短轉移指令
指令格式 loop s(如果(cx)!=0,轉移到標號處執行)
可以這樣理解:
(cx)--
if((cx)!=0) jmp short s
9.9根據位移進行轉移的意義以及編譯器對轉移位移超界的檢測
jmp short s
jmp near ptr s
jcxz s
loop s
均為根據當前指令相對於標號處的位移進行更改IP的轉移指令,這些指令的機器碼中並不包括跳轉目的地址,僅僅包含位移量。
當時針對短轉移跳轉指令,如果跳轉位置超過正的127或者負的128都會出現移位超界,此時編譯器會報錯,務必注意這一點。