《汇编语言》第3版 (王爽)第10章检测点解析

第10章 检测点


检测点10.1:补全程序,实现从内存1000:0000处开始执行指令。
解析: 我们知道retf指令是用栈中的数据,同时修改CS和IP寄存器中的内容,实现远转移,而且是先出栈的数据放入IP中,后出栈的数据放入CS中,所以既然要从1000:0000处开始执行指令,则只需要将1000先入栈,再将0000入栈,那么出栈时就会先将0000出栈放入IP中,再将1000出栈放入CS中。

assume cs:code

stack segment
	db 16 dup(0)
stack ends

code segment
      start:mov ax,stack
            mov ss,ax
	    mov sp,16
	    mov ax,1000H ;先将1000H入栈
	    push ax
	    mov ax,0     ;再将0000H入栈
	    push ax
	    retf
code ends
end start

将上述程序在DOS中运行后,效果如下:
执行RETF前,CS:IP = 076B:0010,执行RETF后,CS:IP = 1000:0000。
在这里插入图片描述
检测点10.2: 下面的程序执行后,AX中的数值为多少?
在这里插入图片描述
解析: 我们知道call指令会将当前的IP压栈后,转到标号出执行指令,但是需要注意的是压栈的是call指令的下一条指令的IP,所以上面程序执行后,AX中的数据为6。

检测点10.3: 下面的程序执行后,ax中的数值为多少?
在这里插入图片描述
解析: 我们知道call far ptr指令实现的是段间转移,会将CS中的段地址和IP中的偏移地址依次入栈,所以上面程序执行完call指令后,会先将段地址1000入栈,再将偏移地址8入栈(注意是下一条指令的地址),然后跳转到s执行,根据栈"先入后出"的原则,执行完pop ax后会先将8取出放入AX中,然后执行add ax,ax后,AX = 8+8 = 16(10H),再将1000H出栈放入BX中,执行完add ax,bx后,AX = 1000H + 10H = 1010H,所以执行后,AX中的数值为1010H

检测点10.4: 下面的程序执行后,ax中的数值为多少?
在这里插入图片描述
解析: 首先将6放入AX中,此时AX = 6,然后将IP中的偏移地址入栈(5入栈)再跳转到偏移地址为6的地址执行mov bp,sp ,将SP中的内容放入bp中,最后执行add ax,[bp],而段地址默认在SS中,即此时相当于 AX = AX + ((ss)*16+(sp)) = 6 + 5 = 11 = BH

检测点10.5: (1)下面的程序执行后,ax中的数值为多少?(注意:用call指令的原理来分析,不要在Debug中单步跟踪来验证你的结论。对于此程序,在Debug中单步跟踪的结果,不能代表CPU的实际执行结果。)

assume cs:code
stack segment
	dw 8 dup(0)
stack ends
code segment
	start:mov ax,stack  ;将栈的段地址放入AX中
		  mov ss,ax     ;将AX中的内容放入SS中
		  mov sp,16     ;设置栈顶指针
		  mov ds,ax     ;将AX中的内容放入DS中,到此AX中的内容并未改变,所以还是栈的段地址
		  mov ax,0      ;此时AX中为0
		  call word ptr ds:[0EH]   ;先将下一跳指令的IP入栈,然后跳转到ds:[0EH]内存单元中的地址,由于DS也指向栈段,并且刚刚将IP入栈了,所以此时还是跳转到下一跳指令
		  inc ax        
		  inc ax
		  inc ax        ;执行完后AX = 3
		  mov ax,4c00h
		  int 21h
code ends
end start

(2)下面的程序执行后,ax和bx中的数值为多少?

assume cs:code
data segment
	dw 8 dup(0)
data ends
code segment
	start:mov ax,data  ;将数据段的段地址放入AX中
	      mov ss,ax    ;将AX中的内容放入SS中
	      mov sp,16    ;设置栈顶指针
	      mov word ptr ss:[0],offset s   ;将s处的偏移地址放如ss:[0]处
	      mov ss:[2],cs ;将当前CS中的内容放入ss:[2]中
	      call dword ptr ss:[0]   ;将下一条指令的CS:IP压栈,然后跳转到以ss:[0]内存单元中数据为地址的地方,即s处
	      nop
	    s:mov ax,offset s    ;将s的偏移地址放入AX中
	      sub ax,ss:[0cH]    ;由于ss:[0cH]中存放的刚刚入栈的IP即nop指令的IP,而AX中存放的又是s处的IP,二者相差1(nop占一个字节),所以相减后,AX = 1
	      mov bx,cs          ;将CS中的内容放入BX中
	      sub bx,ss:[0eH]    ;由于ss:[0eH]中存放的是刚刚入栈的CS,所以相减为0 BX = 0
	      
	      mov ax,4c00h
	      int 21h
code ends
end start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值