一些轉移指令
阿新 • • 發佈:2019-01-22
轉移指令
# 8086cpu的轉移指令分為以下幾類:
* 無條件轉移指令(如:jmp)
* 條件轉移指令
* 迴圈指令(如:loop)
* 過程(相當於函式)
* 中斷
# 操作符offset在組合語言中是由編譯器處理的符號,它的功能是取得標號的偏移地址 a. 無條件轉移: # jmp為無條件轉移,可以只改變IP,也可以同時修改CS和IP jmp指令要提供兩條資訊: * 轉移的目的地址 * 轉移的距離(段間距離,段內短轉移,段內近轉移) //==============================段內轉移==================================== 1)jmp short 標號 (轉到標號處執行指令) 這種格式的jmp指令實現的是段內短轉移,它對IP的修改範圍為-128-127,即向前轉移最多 可以越過128個位元組,向後轉移最多可以越過127個位元組 assume cs:codesg codesg segment start: mov ax,0 jmp short s add ax,1 //此處ax+1未執行,由jmp直接跳過了,所以最終ax為1 s:inc ax codesg ends end start 實際上,指令"jmp short 標號"的功能為ip=ip+8位位移 * 8位位移="標號"處的地址->jmp指令後的第一個位元組的地址 * short指令表明此處的位移為8位位移 * 8位位移的範圍為-128-127,用補碼錶示 * 8位位移由編譯程式在編譯時算出 2) jmp near ptr 標號(和jmp short 標號類似,不過是段內近轉移) 指令"jmp near ptr 標號"的功能為ip=ip+16位位移 * 16位位移="標號"處的地址->jmp指令後的第一個位元組的地址 * near指令表明此處的位移為16位位移 * 16位位移的範圍為-32769-32768,用補碼錶示 * 16位位移由編譯程式在編譯時算出 3)jmp 16位暫存器 功能:IP=16位暫存器 4)jmp word ptr 記憶體單元地址 功能:從記憶體單元地址處開始存放一個字,是轉移的目的的偏移地址 //==============================段間轉移======================================= 1)jmp far ptr 標號(實現的是段間轉移,又稱為遠轉移) 功能: * cs=標號所在段的段地址 * ip=標號所在段中的偏移地址 2)jmp dword ptr 記憶體單元地址 功能:從記憶體單元地址處開始存放兩個字,高地址處的字是轉移目的的段地址,低地址處是 偏移地址
b.有條件轉移
1)jcxz指令 jcxz指令為有條件轉移指令,所有的有條件轉移指令都是短轉移,在對應的機器碼中包含轉移的位移 而不是目的地址。對IP的修改範圍都為-128-127 指令格式: jcxz 標號 如果cx=0,則轉移到標號處執行,相當於(if(cx==0) jmp short 標號) 2)loop loop為迴圈指令,所有的迴圈指令都是短轉移,在對應的機器碼中包含轉移的位移,對ip的修改範圍 為-128-127 指令格式:loop 標號 每次執行後cx=cx-1,如果cx!=0,則轉移到標號處執行,與jcxz相反,相當於 if(--cx!=0) jmp short 標號
!!!注意使用轉移指令時,比如
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start: mov ax,0
s: nop //什麼也不做,佔一個位元組
nop
mov di,offset s //di儲存s標誌所在的偏移地址
mov si,offset s2 //si儲存s2標誌所在偏移地址
mov ax,cs:[si]
mov cs:[di],ax //將s標誌處的機器碼改為s2標誌處的機器碼,
s0: jmp short s //跳轉到標誌s處
s1: mov ax,0
int 21h
mov ax,0
s2: jmp short s1
nop
codesg ends
end start
來分析一下上面程式,從程式碼段的start標誌開始執行:
1:mov ax,0
2:nop
3:nop
4:mov di,offset s
5:mov si,offset s2
6:mov ax,cs:[si]
7:mov cs:[di],ax /*這裡將cs:[di]處的機器碼改為cs:[si]的,看一
下cs:[si],si是標誌s2處的偏移地址,s2處指令
為 jmp short s1
nop
由於轉移指令不是記錄偏移地址,而是轉移的距離,編譯器
算出地址,所以這裡機器碼中儲存s2到s1的距離,由於
向上轉移,所以是負的,大小為位元組數,看一下debug
*/
第8步跳到標誌s中(jmp short s),由於標誌s處機器碼已經改為s2處的機器碼,所以再次跳轉,注意不是跳轉到s1,而是向上跳轉10個位元組,之所以用nop就是為了使得跳轉的位元組大小相同,所以應該跳轉到
mov ax,4c00h
int 21h
程式結束