第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