在debug中的g命令发现的奇怪问题

 编写并安装int 7ch中断例程,功能为完成loop指令的功能。
        参数:(cx)=循环次数,(bx)=位移。
        以上中断例程安装成功后,对下面的程序进行单步跟踪,尤其注意观察int、iret指令执行前后CS、IP和栈中的状态。
        在屏幕中间显示80个“!”。
        应用程序代码(命名为“ show!.asm ”):
        assume cs:code
        code segment
        start:mov ax,0b800h
                        mov es,ax
                        mov di,160*12
                        mov bx,offset s - offset se
                        mov cx,80

                       s:mov byte ptr es:[di],'!'
                          add di,2
                           int 7ch
                          se:nop
                          mov ax,4c00h
                           int 21h

                         code ends
                         end start
        安装程序代码(命名为“ install.asm ”):
        assume cs:code
        code segment
        start:mov ax,cs
                mov ds,ax
                mov si,offset lp
                mov ax,0
                mov es,ax
                mov di,200h
                mov cx,offset lpend - offset lp
                rep movsb

                mov ax,0
                mov es,ax
                mov word ptr es:[4*7ch],200h
                mov word ptr es:[4*7ch+2],0

                mov ax,4c00h
                int 21h

         lp: push bp
             mov bp,sp
             dec cx
             jcxz lpret
             add [bp+2],bx                    ;红色部分模拟了loop指令的功能

        lpret:pop bp
                iret
      lpend:nop                                 ;lp和lpend之间的红色代码并不执行,而是作为数据安装到0:200h及其之后的地址中。以响应int 7ch指令                                                           引发的中断。
        code ends
        end start

Windows中,cmd命令进入虚拟8086模式的DOS,利用masm和link对以上两个代码编译连接生成各自的exe程序。
首先,输入debug install.exe命令,debug程序将install载入内存地址单元中,CS:IP指向start处。此时,输入d 0000:01f0 01f3查看到的数值为:00 00 00 00,这里是中断类型码7ch号对应的中断向量列表中的位置,0000:01f0中存储的是中断处理程序IP的值,0000:01f2中存储的是其CS的值:

 

图片


用u命令查看debug中显示的代码 及其对应的内存单元地址。 如下图示:

图片

 

现跟踪调试,而不是用t命令进行单步跟踪,输入命令:g 001a,从CS:IP开始指向的0ba0:0000处开始执行,一直到0ba0:001a为止。

 

图片 


此处debug中显示的代码为mov prt word [01F0],0200,右下角显示DS:01F0=0200,此处意为继续执行此处代码后,传送到在内存地址ds:[01f0]中的数据为0200,段寄存器竟然为DS。可是,源代码为mov word ptr es:[4*7ch],200h,在0BA0:0014和0BA0:0017地址处的代码(也就是前两行代码)设置了段寄存器为ES,已经非常明确段寄存器为ES了,这里的g命令为什么忽略它的存在而“自作主张”地设置在

 DS中呢?应用程序执行的最终结果是引起不在意料之中的错误中断例程!奇怪啊。。哪位高手看到了这个问题,请指示!!

接着t命令继续执行,这时出现了正常的ES:0IF2=0000。如下图:

 

图片


然后,d 0000:01f0 01f3 查看其中的数值是否为00 02 00 00,可是仍然还是00 00 00 00

 

图片

 

 


如果输入命令 g 0021, 从CS:IP最初指向的0ba0:0000处开始执行,一直到0ba0:0021为止,此时CS:IP指向 mov word ptr es:[4*7ch+2],0,当然还未执行这句代码 。也会出现同样的问题(这里可以肯定会出现同样的问题,尽管向0000:01f2处传送的0):

 

图片

 

而此时继续输入d 0000:01f0 01f1命令查看前一句代码: mov word ptr es:[4*7ch],200h是否正确执行了,结果却是正确的,es:[4*7ch]地址中的数值是预想中的0200。  如下图:  

图片


注:以上提到的问题,是给中断处理程序设置中断向量列表的,也就是把中断处理程序第一行代码所在的0:200h地址登记到中断类型码7c号中,其内存字单元地址为0:4*7ch和0:4*7ch+2,分别存储的是中断处理的偏移地址IP和段地址CS。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值