彙編語言(王爽)第九章

第九章

可以修改IP或者同時修改CS和IP的指令統稱爲轉移指令

只修改IP的爲段內轉移,如:jmp ax

同時修改CS和IP的爲段間轉移,如:jmp 1000:0

段內轉移又分爲:短轉移和近轉移

短轉移IP的修改範圍爲-128~127

近轉IP的修改範圍爲-32768~32767

8086轉移指令分類

· 無條件轉移指令(如:jmp)

· 條件轉移指令

· 循環指令(如:loop)

· 過程

· 中斷

9.1 操作符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

有如下程序段,將該程序中s處的一條指令複製到s0處

assume cs:codesg
codesg segment
	s:	mov ax,bx			; 機器碼佔兩個字節
		mov si,offset s
		mov di,offset s0
		mov ax,cs:[si]
		mov cs:[di],ax
	s0: nop			
		nop					; nop的機器碼佔兩個字節
codesg ends
end s

9.2 jmp指令

jmp指令要給出兩種信息

1、轉移的目的地址

2、轉移的距離

不同的方法有不同的jmp格式

9.3 依據位移進行轉移的jmp指令

jmp short 標號(轉到標號處執行指令)

這種格式實現段內短轉移,對IP的修改範圍爲-128~127

如下程序,ax只進行了一次加1操作

assume cs:codesg

codesg segment
	start:	mov ax,0
			jmp short s
			add ax,1
		s:  inc ax
codesg ends
end start

一般的彙編指令中,立即數都會在對應的機器指令中出現,但是將上述代碼翻譯成機器語言,發現 jmp short s對應的機器碼爲EB03,修改程序

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

修改後s的偏移地址與之前的位置不同,但 jmp short s對應的機器碼仍然爲EB03,結論是CPU在執行jmp指令的時候並不需要轉移的目的地址,至於爲什麼是EB 03,因爲當前地址爲CS:0008H,目標地址爲CS:000BH,所以將IP值加3就是目標指令,因爲這兩個程序jmp指令轉移的位移相同,所以都爲EB 03

因此 jmp short 標號指令所對應的機器碼中,並不包含轉移的目的地址,而包含轉移的位移,是編譯器根據彙編指令中的標號計算出來的

在這裏插入圖片描述

注意計算位移的方法,因爲讀取了jmp指令後,IP會指向下一條指令,所以位移是下一條指令地址與目標指令地址的差

該位移爲8位,補碼錶示(所以範圍爲-128~127)

對應的 jmp near ptr實現段內近轉移

位移爲16位(範圍-32768~32767)

9.4 轉移的目的地址在指令中的jmp指令

jmp far ptr 標號實現段間轉移,又稱爲遠轉移

far ptr指明瞭用標號的段地址和偏移地址修改CS和IP

(CS)=標號所在段的段地址 (IP)=標號在段中的偏移地址

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

格式 jmp 16位reg

(IP)=(16位reg)

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

jmp word ptr 內存單元地址(段內轉移)

某內存單元地址處存放着一個字,是轉移的目的偏移地址

內存單元地址可用尋址方式的任一格式給出

jmp word ptr ds:[0]
jmp word ptr [bx]

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}=0 (IP)=0123H

補全程序,使jmp指令執行後,CS:IP指向程序的第一條指令

assume cs:code

data segment
	dd 12345678H
data ends

code segment
	start:	mov ax,data
			mov ds,ax
			mov bx,0
			mov [bx],bx	;mov [bx],word ptr 0或mov [bx],offset start
			mov [bx+2],cs	; mov [bx+2],code
			jmp dword ptr ds:[0]
code ends
end start

9.7 jcxz指令

jcxz指令爲有條件轉移指令,所有的有條件轉移指令都是短轉移,在對應的機器碼中包含轉移的位移,對IP的修改範圍是-128~127

格式:jcxz 標號(如果(cx)=0,轉移到標號處執行)

當(cx) != 0,什麼也不做,程序向下執行

功能等價於 if ((cx) == 0) jmp short 標號;

補全編程,利用jczx指令,實現在內存2000H段中查找第一個值爲0的字節,找到後,將它的偏移地址存儲在dx中

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

9.8 loop指令

所有的循環指令都是短轉移,對應的機器碼中包含轉移的位移,對IP的修改範圍是-128~127

指令格式 loop 標號((cx)=(cx)=1,如果(cx) != 0,轉移到標號處執行)

等價於

(cx)–

if ((cx) != 0) jmp short 標號;

補全編程,利用jczx指令,實現在內存2000H段中查找第一個值爲0的字節,找到後,將它的偏移地址存儲在dx中

assume cs:code
code segment
	start:	mov ax,2000H
			mov ds,ax
			mov bx,0
		s:	mov cl,[bx]
        	mov ch,0
        	inc cx		; loop s處cx也會減一,因此如果cx爲0,loop執行後
        	inc bx		; cx爲-1,不能正常退出循環,因此先再加1
        	loop s
	   ok:  dec bx		; dec效果與inc相反,自減
	   		mov dx,bx
	   		
	   		mov ax,4c00h
	   		int 21h
code ends
end start

9.9 根據位移進行轉移的意義

方便程序段在內存中的浮動裝配,如

	mov cx,6
	mov ax,10h
s:  add ax,ax
	loop s 

這段程序在內存的不同位置都可正確執行,無論s處的指令的實際地址是多少,loop指令的轉移位移是不變的

9.10 編譯器對轉移位移超界的檢測

assume cs:code

code segment
	start:	jmp short s
			db 128 dup (0)
		s:  mov ax,0ffffh
code ends
end start

jmp short s的轉移範圍是-128~127,IP最多向後移動127個字節

在Debug中使用的指令如"jmp 2000:0100"的轉移指令,編譯時會報錯,不能在源程序中使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章