1. 程式人生 > >匯編入門學習筆記 (八)—— 轉移指令

匯編入門學習筆記 (八)—— 轉移指令

無條件轉移 fse ear tom 內存 star space off 編譯器

瘋狂的暑假學習之 匯編入門學習筆記 (八)—— 轉移指令


參考: 《匯編語言》 王爽 第9章


能夠改動ip或者同一時候改動cs和ip的指令統稱為轉移指令。

8086CPU轉移行為分為:

段內轉移:僅僅改動ip

段間轉移:同一時候改動cs和ip

段內轉移按ip改動的範圍可分為:

短轉移:ip改動範圍 -128~127

近轉移:ip改動範圍 -32768~32767


轉移指令分為:

無條件轉移指令。如 jmp

條件轉移指令

循環指令。如 loop

過程。

中斷。


1. offset,nop指令


offset 獲取標號的偏移地址

nop 占用1一個字節

樣例:

assume cs:code

code segment

start:	mov ax,bx
	mov si,offset start
	mov di,offset s
	
	mov ax,cs:[si]
	mov cs:[di],ax
	
s:	nop
	nop
code ends

end start


2. 根據位移進行轉移的jmp指令


(1)jmp short 標號


是段內短轉移。

表示轉移到指定的標號處。且轉移的距離範圍為-128~127


用debug查看此指令時,會看見機器碼。不會保存標號的地址,自會保存轉移的距離


(2)jmp near ptr 標號


是段內近轉移,轉移的距離範圍為-32768~32767。其它與jmp short 標號同樣


2. 轉移地址在寄存器中的jmp指令


jmp 16位 reg


表示 (IP)=(16位 reg


3.轉移地址在內存中的jmp指令


(1)jmp word ptr 內存單元地址


是段內近轉移。


樣例:轉移到偏移地址為0123H的指令去,即使(IP)= 0123H

mov ax,0123H
mov ds:[0],ax
jmp word ptr ds:[0]

(2)jmp dword ptr 內存單元地址


是段間轉移


高地址表示轉移的段地址

低地址表示偏移地址


用debug查看機器碼,能夠發現。它是保存了段地址與偏移地址,而不是像段內轉移的指令時保存轉移的距離


樣例:轉移到段地址為0,偏移地址為0123H的指令去。即使得(CS)= 0。(IP)= 0123H

mov ax,0123H
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]



4. jcxz 指令


jcxz 指令為條件轉移指令。當cx為0時,轉移(與loop剛剛相反)。

全部條件轉移指令都是短轉移。


樣例:在內存2000H段中查找第一個值位0 的字節。並把它的偏移指定存儲在dx中。

assume cs:code

code segment

start:	mov ax,2000H
	mov ds,ax
	mov bx,0
s:	mov ch,0
	mov cl,[bx]
	jcxz ok
	inc bx
	jmp short s
ok:	mov dx,bx
	mov ax,4c00H
	int 21H
code ends
end start


5. jmp指令具體分析


jmp s

jmp short s

jmp near ptr s

jmp far ptr s


向前轉移:

在像前轉移時。編譯器能夠在讀到標號s後記下AC(地址計算器)的值as。在讀到jmp ...s (上面5種)後記下AC的值aj。編譯器能夠用as-aj計算出disp


(1)假設disp 在 -128~127 內

上面的每一種指令都將轉化為 jmp short s

(2)假設disp 在 -32768~32767

對於jmp short s會編譯錯誤

對於jmp s,jmp near ptr s會產生jmp near ptr s所相應的機器碼。

對於jmp far ptr s,所相應的機器碼為:EA 偏移地址 段地址。


先後轉移:

因為不能確定s位置,編譯器先將上面的指令都當做 jmp short s來讀取。記下jmp ..s 指令的位置和AC的值aj。

對於jmp short s 編譯器生成一個EB和一個nop指令

對於jmp near ptr s 編譯器生成一個EB和兩個nop指令

對於jmp far ptr s 編譯器生成一個EB和四個nop指令


當讀到s時,記下AC的值as,計算disp = as - aj

(1)假設disp 在 -128~127 內

指令都為 EB disp 。它們後面的一個nop變成8位的disp 。jmp s(1個)、jmp near ptr s (1個)跟jmp far ptr s (3個) nop指令不變

(2)假設disp 在 -32768~32767 內

對於jmp short s會編譯錯誤

jmp s、jmp near ptr s 後面 兩個nop變成轉移的16位disp。

jmp far ptr s 這填上對應的段地址。偏移地址。


6. 分析一個奇怪的程序


assume cs:code

code segment
	
	mov ax,4c00h
	int 21h
		
start:	mov ax,0
s:	nop
	nop
	
	mov di,offset s
	mov si,offset s2
	mov ax,cs:[si]
	mov cs:[di],ax
	
s0:	jmp short s
	
s1:	mov ax,0
	int 21h
	mov ax,0
	
s2:	jmp short s1
	nop
	
code ends

end start
	


追後程序會執行s處的

mov ax,4c00h

int 21h

而正常終止。

為什麽?

debug能夠發現,jmp short s1 拷貝到s處後,由原來的jmp 0018H變成 jmp 0000H。

可是本質的機器碼是EBF6沒變就是ip = ip - 10。







匯編入門學習筆記 (八)—— 轉移指令