汇编语言(王爽)第九章

第九章

可以修改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"的转移指令,编译时会报错,不能在源程序中使用

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值