- 什么是轉移指令:
可以修改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 STARTJMP 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 ENDSJava代碼:
public class Test{ public static void main(String[] args){ int cx = 32; while((--c) != 0){ // 標號處到LOOP指令之間的代碼段 } } }
以上舉的兩個例子都是使用CX暫存器是否為0進行條件判斷的,還有使用標志暫存器作為條件進行指令轉移的指令,詳情查看:《條件轉移指令之使用標志暫存器進行指令轉移》
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285615.html
標籤:其他
