- 什麼是轉移指令:
可以修改IP,或同時修改CS和IP的指令統稱為轉移指令。轉移指令可以通過修改CS和IP的值來實現對CPU執行記憶體某處程式碼的控制
-
段內轉移:指令轉移方式
IP=IP+位移
。等同於JMP 當前IP+需要位移位元組段內轉移只修改IP,還是處於一個CS段地址內,例如:JMP AX
-
段內短轉移:
JMP SHORT 標號
段內短轉移,位移為8bit位,最高位為符號位。剩餘7個bit位可位移,位移間距是:
-128~127
,也就是說在編譯之後,使用JMP SHORT 標號
指令往前轉移最多128個位元組,往後轉移最多127個位元組。程式碼示例:
ASSUME CS:CODE CODE SEGMENT START: MOV AX,0 MOV BX,0 JMP SHORT S ADD AX,1 ; 機器碼:B80100 ADD AX,3 ; 機器碼:B80300 DB 121 DUP(0) S: INC AX CODE ENDS END START
編譯後的機器碼為121個00位元組的機器碼。121+3(B80100)+3(B80300)=127個位元組,如果將DB 121 DUP(0)改成DB 122 DUP(0),那麼程式在MASM 編譯時期就無法通過,因為129個位元組已經完全超過了8位bit。不信的話可以試試
-
段內近轉移:
JMP NEAR PTR 標號
段內近轉移,位移為16個bit位,最高位為符號bit位,剩餘15個bit為可進行位移,位移間距是
-32768~32767
,在編譯之後,使用JMP NEAR PTR 標號
轉移指令至多往前轉移32768個位元組,往後至多轉移32767位元組。程式碼示例:
ASSUME CS:CODE CODE SEGMENT START: MOV AX,0 MOV BX,0 JMP NEAR PTR S ADD AX,2 DB 128 DUP(0) S: INC AX CODE ENDS END START
JMP NEAR PTR 標號
編譯後的機器碼為E90000。後面四位就是位移範圍,低位在前,高位在後。用法與JMP SHORT
基本一致,只不過前者適用於需要更大幅度的單元跳轉的場景 -
為啥近轉移比短轉移多了個
PTR
關鍵字?這是網上搜尋到的一句話:
彙編裡面 ptr 是規定 的 字 (既保留字),是用來臨時指定型別的
-
-
段間轉移:
JMP FAR PTR 標號
段間轉移,同時修改CS和IP的值,可跨越不同段直接進行指令轉移。等同於
JMP CS:IP
。同時CS=標號所在段地址,IP=標號所在段地址偏移量。也就是說最大轉移幅度應該是(cs*10H)+IP=FFFFF。相當於20個bit位進行位移。最大幅度應該是-1,048,576~1,048,575
個位元組。 -
使用記憶體單元進行指令轉移
-
使用記憶體單元進行近轉移:
JMP WORD PTR 記憶體單元地址
從記憶體單元地址處開始存放著一個字,是轉移目的地指令的偏移地址。
偏移地址計算方式:JMP DS:[BX]。將BX指向的記憶體單元中的資料用於IP暫存器的值。跳轉到指定的位置。偏移量範圍參考:
段內近轉移
-
使用記憶體單元進行段間轉移:
JMP DWORD PTR 記憶體單元地址
-
-
有條件轉移
所有有條件轉移指令都是短轉移
,在對應的機器碼中包含轉移的位移,而不是目的地址。對IP的修改範圍參考段內短轉移
-
JCXZ 指令
JCXZ 標號
為有條件轉移指令之一,它用於判斷CX是否等於0,如果等於0,則執行指令轉移,否則它什麼都不做,程式繼續往下執行,用Java語言的語法表示為:if(cx == 0){jmp ip}。這樣舉例或許更好理解JCXZ指令的作用程式碼示例:
ASSUME CS:CODE,DS:DATA CODE SEGMENT START: MOV AX,DATA MOV DS,AX MOV AX,0 MOV BX,0 S: MOV CL,DS:[BX] ; 將記憶體單元中的值取出,儲存到CL中 JCXZ SAVE ; 如果CX==0時,轉移到SAVA標號處,儲存當前BX的偏移量 INC BX ; 如果CX!=0時,BX+1,也就是偏移量+1。繼續轉移到S標號處執行 JMP SHORT S SAVE: MOV DX,BX MOV AH,4CH INT 21H CODE ENDS DATA SEGMENT DB 12,20,32,00,36 DATA ENDS END START
-
LOOP 指令
LOOP 標號
是一個迴圈指令,但是也是屬於有條件轉移指令的一種。需要注意的是所有迴圈指令都是短轉移
。它判斷CX中的值,是否需要進行指令轉移。跟JCXZ
指令恰恰相反,LOOP指令用判斷CX-1之後是否不等於0,如果不等於0則轉移到標號處。如果等於0,則程式往下執行。用Java語言表示的話,應該是下面程式碼所執行的效果,其中while就相當於LOOP指令,每次指令LOOP指令轉移時,先將CX中的值-1,然後在判斷CX不等於0Assembly程式碼:
ASSUME CS:CODE CODE SEGMENT MOV CX,32 S: ; LOOP迴圈體程式碼段,這裡只能有125個位元組哦 LOOP S COED ENDS
Java程式碼:
public class Test{ public static void main(String[] args){ int cx = 32; while((--c) != 0){ // 標號處到LOOP指令之間的程式碼段 } } }
以上舉的兩個例子都是使用CX暫存器是否為0進行條件判斷的。還有使用標誌暫存器作為條件進行指令轉移的指令,詳情檢視:《條件轉移指令之使用標誌暫存器進行指令轉移》
-