(十二)《汇编语言(王爽)》 | 检测点 9.1、9.2、9.3


1. 预备知识

  • 转移指令:可以修改 IP,或同时修改 CS 和 IP 的指令。前面广泛使用的 loop 指令就是一种转移指令。
  • 8086CPU 中的转移行为有以下两类:只修改 IP 时称为段内转移(段寄存器内容不变),同时修改 CS 和 IP 时称为段间转移
  • jmp near ptr 标号实现段内近转移,近转移中 IP 可修改范围为 -32768~32767。
  • jmp far ptr 标号实现段间远转移,该指令执行后,(CS) 等于标号所在段的段地址,(IP)等于等于标号所在段的偏移地址。
  • jmp 16位寄存器实现的功能为:(IP)等于该 16 位寄存器的值。
  • jmp word ptr 内存单元地址表示段内转移,目的偏移地址由内存单元给出,且操作单位为
  • jmp dword ptr 内存单元地址表示段间转移,目的段地址由内存单元高地址给出、偏移地址由低地址给出,操作单位为双字
  • jcxz 标号,如果 (CX)=0,则转移到标号处执行;如果 (CX)≠0,该转移指令什么也不做,程序向下执行。

2. 检测点 9.1

(1)程序如下:

assume cs:code

data segment
	?
data ends

code segment
start:
	mov ax,data
	mov ds,ax			;寄存器DS指向数据段data
	mov bx,0
	jmp word ptr [bx+1]	;段内转移,偏移地址由[bx+1]给出
code ends
end start

若要使程序中的 jmp 指令执行后,CS:IP 指向程序的第一条指令,在 data 段中应该定义哪些数据?

  • jmp word ptr [bx+1] 实现段内转移,且 jmp 指令执行后 CS 不变、(IP)=ds:[bx+1]。
  • 由于第一条指令的偏移地址为 0,要使 CS:IP 指向第一条指令,则 ds:[bx+1] 的值为零,而 ds:[bx+1] 表示 data 段的第二个字节(mov bx,0)。所以在 data 段中将第三、四个字节定义为零即可(不唯一):
data segment
	db 4 dup (0)	;使用dup指令定义4个字节,值都是0
data ends

运行完 jmp 指令后,程序又从第一条指令开始执行,进入死循环。

(2)程序如下:

assume cs:code

data segment
	dd 12345678H
data ends

code segment
start:
	mov ax,data
	mov ds,ax
	mov bx,0
	mov [bx],____
	mov [bx+2],____
	jmp dword ptr ds:[0]
	
	mov ax,4c00h
	int 21h
code ends
end start

补全程序,使 jmp 指令执行后,CS:IP 指向程序的第一条指令。

  • jmp dword ptr ds:[0] 实现段间转移,目的段地址由内存单元高地址给出、偏移地址由内存单元低地址给出。
  • 程序中内存单元的值是 ds:[0],结合数据段的内容为 12345678h。所以,jmp 执行执行后,目的段地址(CS)为 5678h、偏移地址(IP)为 1234h。显然,待填空部分操作的是数据段的内存单元,即改变数据段的内容使 jmp 执行后 CS:IP 指向程序的第一条指令。
  • 覆盖数据段的内容,高地址(CS)为寄存器 CS 的值、低地址(IP)为 0。代码段部分为:
code segment
start:
	mov ax,data
	mov ds,ax
	mov bx,0
	mov [bx],bx				;将寄存器BX的内容赋值给数据段中的低地址
	mov [bx+2],cs			;将寄存器CS的内容赋值给数据段中的高地址
	jmp dword ptr ds:[0]
	
	mov ax,4c00h
	int 21h
code ends

(3)用 Debug 查看内存,结果如下:

2000:1000 BE 00 06 00 00 00 ......

则此时,CPU 执行指令:

mov ax,2000H
mov es,ax
jmp dword ptr es:[1000H]

后,寄存器 CS 和寄存器 IP 的值为多少?

  • jmp dword ptr es:[1000H] 实现段间转移,目的段地址由内存单元高地址给出、偏移地址由内存单元低地址给出。
  • 2000:[1000H] 所指内存单元的高地址值为 0006,低地址值为 00BE。所以,(CS)=0006、(IP)=00BE。

3. 检测点 9.2

补全编程,利用 jcxz 指令,实现在内存 2000H 段中查找第一个值为 0 的字节,找到后,将它的偏移地址存储在 dx 中。

assume cs:code

code segment
start:
	mov ax,2000H
	mov ds,ax
	mov bx,0
s:	________
	________
	________
	________
	jmp short s 
ok:	mov dx,bx
	
	mov ax,4c00h
	int 21h
code ends
end start 
  • 注意到 jmp short s 指令实现段内短转移,只修改 IP 的值。该指令执行后,CS:IP 指向标号处对应的指令。
  • jcxz 实现类似于 C 语言中 if ((cx)==0) jmp short 标号 的功能。根据题目要求,当 (cx) 等于零时即找到指定内存中为 0 的单元,并跳转到标号 ok 处结束查找。所以,在查找过程中将查找的值赋值给寄存器 CX 即可实现上述功能。
  • 题目要求把偏移地址存储在寄存器 DX 中,由 mov dx,bx 可知,前面要把偏移地址存储在寄存器 BX 中。因此,在查找过程中将 BX 设置为查找时的偏移地址即可。
  • 现在只有三条指令:给 CX 赋值jcxz 指令增加偏移地址以寻找下一条指令。题目要求查找的单位为字节,而 CX 为 16 位寄存器。又因为题目待查找的是第一个字节,所以将找到的字节赋值给 CL 即可,CH 填充为零。代码段部分为:
code segment
start:
	mov ax,2000H
	mov ds,ax
	mov bx,0
s:	mov cl,ds:[bx]	;将内存单元的值依次赋值给寄存器CL
	mov ch,0		;将CH填充为0,和CL组合判断CX是否为零
	jcxz ok			;如果(CX)等于零则跳转到标号ok处,即结束查找
	add bx,1		;每次向后偏移一个字节
	jmp short s 
ok:	mov dx,bx		;偏移地址存储在寄存器DX中
	
	mov ax,4c00h
	int 21h
code ends

4. 检测点 9.3

补全编程,利用 loop 指令,实现在内存 2000H 段中查找第一个值为 0 的 byte(字节),找到后,将它的偏移地址存储在 dx 中。

assume cs:code

code segment
start:
	mov ax,2000H
	mov ds,ax
	mov bx,0
s:	mov cl,[bx]
	mov ch,0
	________
	inc bx 
	loop s 
ok:	dec bx			;dec与inc指令的功能相反,将对应寄存器/内存单元的值减1
	mov dx,bx

	mov ax,4c00h
	int 21h
code ends
end start 
  • 和上题类似,退出循环 s 后表示找到指定内存中值为 0 的单元。
  • 在执行到 loop s 时首先判断 (CX) 减一后是否为零,如果为零则退出循环,否则继续执行循环体。循环 s 的循环体中前两句为寄存器 CX 赋值,如果 (CX) 等于零表示找到指定值,要使执行到 loop s 时退出循环,此时的 (CX) 必须为 1,所以空缺部分将 (CX) 加 1。
code segment
start:
	mov ax,2000H
	mov ds,ax
	mov bx,0
s:	mov cl,[bx]
	mov ch,0
	add cx,1
	inc bx 			;寄存器BX加1表示偏移1个字节查找下一个字节
	loop s 
ok:	dec bx			;dec与inc指令的功能相反,将对应寄存器/内存单元的值减1
	mov dx,bx

	mov ax,4c00h
	int 21h
code ends

5. 总结

  • jmp 段内转移只修改 IP 的值,段间转移同时修改 CS 和 IP 的值。
  • 转移指令对应机器码中的位移通过当前转移指令后的第一个字节和转移目的地址的差。

  • 15
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值